{"record":{"id":"9c09601a7f34d9c7","repo":"DIYgod/RSSHub","slug":"this-rss-is-disabled-unless-allow-user-supply-uns-9c0960","errorCode":null,"errorMessage":"This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.","messagePattern":"This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'\\.","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/wordpress/index.ts","lineNumber":17,"sourceCode":"import { load } from 'cheerio';\n\nimport { config } from '@/config';\nimport ConfigNotFoundError from '@/errors/types/config-not-found';\nimport type { Data, Route } from '@/types';\nimport got from '@/utils/got';\nimport { parseDate } from '@/utils/parse-date';\nimport parser from '@/utils/rss-parser';\n\nimport { apiSlug, bakeFilterSearchParams, bakeFiltersWithPair, bakeUrl, fetchData, getFilterParamsForUrl, parseFilterStr } from './util';\n\nasync function handler(ctx) {\n    const { url = 'https://wordpress.org/news', filter } = ctx.req.param();\n    const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50;\n\n    if (!config.feature.allow_user_supply_unsafe_domain) {\n        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);\n    }\n\n    if (!/^https?:\\/\\/[^\\s#$./?].\\S*$/i.test(url)) {\n        throw new Error('Invalid URL');\n    }\n\n    const cdn = config.wordpress.cdnUrl;\n    const rootUrl = url;\n\n    const filters = parseFilterStr(filter);\n    const filtersWithPair = await bakeFiltersWithPair(filters, rootUrl);\n\n    const searchParams = bakeFilterSearchParams(filters, 'name', false);\n    const apiSearchParams = bakeFilterSearchParams(filtersWithPair, 'id', true);\n\n    apiSearchParams.append('_embed', 'true');\n    apiSearchParams.append('per_page', String(limit));\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/wordpress/index.ts#L1-L35","documentation":"A ConfigNotFoundError (not a generic Error) thrown because the wordpress route lets the caller supply an arbitrary URL — an SSRF risk. RSSHub refuses to run it unless the operator explicitly opts in by setting ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true. RSSHub maps ConfigNotFoundError to an HTTP error that tells the user the feed is misconfigured rather than broken.","triggerScenarios":"Any call to /wordpress/... while config.feature.allow_user_supply_unsafe_domain is falsy (the default), regardless of the url argument.","commonSituations":"Self-hosted RSSHub where the operator wants to follow arbitrary wordpress blogs but has not enabled the flag; trying the public rsshub.app instance (which does not enable it) with a custom URL.","solutions":["Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true in the RSSHub environment and restart, understanding the SSRF implications.","If you do not control the instance, ask the operator to enable it or run your own.","For wordpress.org/news specifically, use a route that does not require the flag if available."],"exampleFix":"# before (env)\n# (flag absent)\n# after\nALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true","handlingStrategy":"validation","validationCode":"// Check the feature flag up-front in your deployment script\nif (process.env.ALLOW_USER_SUPPLY_UNSAFE_DOMAIN !== 'true') {\n    console.warn('wordpress route disabled — set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true to enable (SSRF risk)');\n}","typeGuard":"function isWordpressDisabledError(e: unknown): boolean {\n    return e instanceof Error && e.name === 'ConfigNotFoundError' && /ALLOW_USER_SUPPLY_UNSAFE_DOMAIN/i.test(e.message);\n}","tryCatchPattern":"try {\n    return await wordpressHandler(ctx);\n} catch (e) {\n    if (isWordpressDisabledError(e)) {\n        return ctx.json({ error: 'Route disabled by admin. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true.' }, 501);\n    }\n    throw e;\n}","preventionTips":["Treat ALLOW_USER_SUPPLY_UNSAFE_DOMAIN as a security decision — document the SSRF exposure before enabling.","When enabling, also restrict outbound egress at the network layer to limit SSRF blast radius.","Prefer type-specific RSSHub routes over the generic wordpress route when available."],"tags":["wordpress","config","ssrf","security","config-not-found"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}