{"record":{"id":"7710bccec1cd608a","repo":"DIYgod/RSSHub","slug":"this-rss-is-disabled-unless-allow-user-supply-uns-7710bc","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":"error_code","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"warning","filePath":"lib/routes/rsshub/transform/html.ts","lineNumber":63,"sourceCode":"| \\`itemPubDateAttr\\` | The attributes of \\`pubDate\\` element as pubDate                                                          | \\`string\\`        | Element html           |\n| \\`itemContent\\`     | The HTML elements as \\`description\\` in \\`item\\` using CSS selector ( in \\`itemLink\\` page for full content ) | \\`string\\`        |                        |\n| \\`encoding\\`        | The encoding of the HTML content                                                                        | \\`string\\`        | utf-8                  |\n\nParameters parsing in the above example:\n\n| Parameter     | Value                                     |\n| ------------- | ----------------------------------------- |\n| \\`url\\`         | \\`https://wechat2rss.xlab.app/posts/list/\\` |\n| \\`routeParams\\` | \\`item=div[class='post-content'] p a\\`      |\n\nParsing of \\`routeParams\\` parameter:\n\n| Parameter | Value                           |\n| --------- | ------------------------------- |\n| \\`item\\`    | \\`div[class='post-content'] p a\\` |`,\n    handler: async (ctx) => {\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        const url = ctx.req.param('url');\n        const response = await got({\n            method: 'get',\n            url,\n            responseType: 'arrayBuffer',\n        });\n\n        const routeParams = new URLSearchParams(ctx.req.param('routeParams'));\n        const encoding = routeParams.get('encoding') || 'utf-8';\n        const decoder = new TextDecoder(encoding);\n\n        const $ = load(decoder.decode(response.data));\n        const rssTitle = routeParams.get('title') || $('title').text();\n        const item = routeParams.get('item') || 'html';\n        let items: DataItem[] = $(item)\n            .toArray()\n            .slice(0, 20)","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/rsshub/transform/html.ts#L45-L81","documentation":"The generic HTML transformation route /<transform>/html lets a user feed an arbitrary URL into RSSHub and extract elements from the response. Because that is an SSRF surface, the route is disabled unless the RSSHub operator has explicitly opted in by setting `config.feature.allow_user_supply_unsafe_domain` to true. The check runs at the very top of the handler, before the user-supplied URL is fetched.","triggerScenarios":"Any request to /rsshub/transform/html/... on an instance where `ALLOW_USER_SUPPLY_UNSAFE_DOMAIN` is not `true`. The throw fires before `got({url})`, so no outbound request is attempted.","commonSituations":"Default RSSHub deploy (the flag defaults to false); a user discovers the transform route in the docs and tries it on rsshub.app, which leaves the feature off for security.","solutions":["If you operate the instance and accept the SSRF risk, set `ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true` in the RSSHub environment and restart. Restrict network egress at the firewall layer as defense-in-depth.","If you do not control the instance, run your own RSSHub with the flag enabled rather than asking the public instance to enable it.","Prefer route-specific feeds when one exists for the target site — they are not gated by this flag."],"exampleFix":"// before\n# .env — flag unset\n\n// after\n# .env\nALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true","handlingStrategy":"validation","validationCode":"if (!config.feature?.allow_user_supply_unsafe_domain) {\n    return ctx.body('Transform route requires ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true.', 403);\n}","typeGuard":"const isUnsafeDomainAllowed = (c: typeof config): boolean =>\n    c.feature?.allow_user_supply_unsafe_domain === true;","tryCatchPattern":null,"preventionTips":["Treat the flag as opt-in for a reason — pair it with network egress controls.","Document the SSRF risk in your deploy notes whenever you enable it.","Run a dedicated instance for transform routes, isolated from your main RSSHub."],"tags":["config-missing","security","ssrf-guard"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}