{"record":{"id":"f23e4dd9ad4e5685","repo":"DIYgod/RSSHub","slug":"this-rss-is-disabled-unless-allow-user-supply-uns-f23e4d","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":"warning","filePath":"lib/routes/misskey/user-timeline.ts","lineNumber":52,"sourceCode":"        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'User timeline',\n    maintainers: ['siygle', 'SnowAgar25', 'HanaokaYuzu'],\n    handler,\n};\n\nasync function handler(ctx): Promise<Data> {\n    const username = ctx.req.param('username');\n    const [, pureUsername, site] = username.match(/@?(\\w+)@(\\w+\\.\\w+)/) || [];\n    if (!pureUsername || !site) {\n        throw new InvalidParameterError('Provide a valid Misskey username');\n    }\n    if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {\n        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);\n    }\n\n    const routeParams = querystring.parse(ctx.req.param('routeParams'));\n    const withRenotes = fallback(undefined, queryToBoolean(routeParams.withRenotes), false);\n    const mediaOnly = fallback(undefined, queryToBoolean(routeParams.mediaOnly), false);\n    const simplifyAuthor = fallback(undefined, queryToBoolean(routeParams.simplifyAuthor), false);\n\n    // Check for conflicting parameters\n    if (withRenotes && mediaOnly) {\n        throw new InvalidParameterError('withRenotes and mediaOnly cannot both be true.');\n    }\n\n    const { accountData, avatarUrl } = await utils.getUserTimelineByUsername(pureUsername, site, {\n        withRenotes,\n        mediaOnly,\n    });\n\n    return {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/misskey/user-timeline.ts#L34-L70","documentation":"Thrown as ConfigNotFoundError by the Misskey user-timeline route — the same SSRF allow-list guard as the other Misskey routes. After the acct regex validates pureUsername and site, the host portion (site) must be in utils.allowSiteList unless ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is enabled.","triggerScenarios":"The username acct is syntactically valid (matched the regex) but the extracted site is not on the curated allow-list and the unsafe-domain flag is off. The handler refuses to call https://<site>/api/users/show etc.","commonSituations":"User follows someone on a niche/self-hosted Misskey instance not in RSSHub's list; the operator hasn't enabled the unsafe-domain toggle.","solutions":["Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true on a self-hosted RSSHub (recognize the SSRF implications) and restart.","Or target a user on an allow-listed instance.","Or contribute the instance to utils.allowSiteList if reputable."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {\n    throw new ConfigNotFoundError(`Host '${site}' not in allow-list. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true (self-host) or use an allowed instance.`);\n}","typeGuard":"function isAllowedSite(site: string, allowList: string[], unsafeAllowed: boolean): boolean {\n    return typeof site === 'string' && (allowList.includes(site) || unsafeAllowed);\n}","tryCatchPattern":null,"preventionTips":["Validate the host portion of the acct against the allow-list before deeper processing.","Prefer adding reputable instances to allowSiteList over the global unsafe flag.","Combine the acct-parse and allow-list checks into one helper shared by all misskey routes."],"tags":["ssrf-guard","allow-list","missing-config","misskey","unsafe-domain"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}