{"record":{"id":"7d9a6425105736be","repo":"DIYgod/RSSHub","slug":"this-rss-is-disabled-unless-allow-user-supply-uns-7d9a64","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":null,"severity":"warning","filePath":"lib/routes/mastodon/timeline-remote.ts","lineNumber":43,"sourceCode":"    features: {\n        requireConfig: false,\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: 'Instance timeline (federated)',\n    maintainers: ['hoilc'],\n    handler,\n    description: 'If the instance address is not `mastodon.social` or `pawoo.net`, then the route requires `ALLOW_USER_SUPPLY_UNSAFE_DOMAIN` to be `true`.',\n};\n\nasync function handler(ctx) {\n    const site = ctx.req.param('site');\n    const only_media = ctx.req.param('only_media') === 'true' ? 'true' : 'false';\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 url = `http://${site}/api/v1/timelines/public?remote=true&only_media=${only_media}`;\n\n    const response = await got.get(url, { headers: utils.apiHeaders(site) });\n    const list = response.data;\n\n    return {\n        title: `Federated Public${ctx.req.param('only_media') === 'true' ? ' Media' : ''} Timeline on ${site}`,\n        link: `https://${site}`,\n        item: utils.parseStatuses(list),\n    };\n}\n","sourceCodeStart":25,"sourceCodeEnd":57,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mastodon/timeline-remote.ts#L25-L57","documentation":"ConfigNotFoundError thrown by the Mastodon federated/remote-timeline route when :site is not allowlisted and ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is false. Mirrors the local-timeline guard; the route subsequently fetches http://<site>/api/v1/timelines/public?remote=true.","triggerScenarios":"GET /mastodon/timeline-remote/:site/:only_media? where :site is not in allowSiteList and the feature flag is off.","commonSituations":"Watching the federated timeline of a non-allowlisted instance; public RSSHub with guard enabled; wrong/typo'd site hostname.","solutions":["Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true for private/trusted setups.","Set MASTODON_API_HOST to your instance to allowlist it.","Ensure the site is a reachable Mastodon host.","On public deployments, keep the guard and request an allowlist addition."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const ALLOWED = ['mastodon.social','pawoo.net','fosstodon.org', config.mastodon.apiHost].filter(Boolean);\nif (!ALLOWED.includes(site) && !config.feature.allow_user_supply_unsafe_domain) {\n    throw new ConfigNotFoundError('Instance not allowlisted; set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true or MASTODON_API_HOST');\n}","typeGuard":"const isAllowlistedSite = (site: string): boolean =>\n    ['mastodon.social','pawoo.net','fosstodon.org', config.mastodon.apiHost].filter(Boolean).includes(site);","tryCatchPattern":null,"preventionTips":["Validate the site at the boundary.","Prefer MASTODON_API_HOST over disabling the SSRF guard.","Keep the guard on for public deployments."],"tags":["mastodon","config","ssrf","config-not-found","security"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}