{"record":{"id":"ad4ced55b3d91826","repo":"DIYgod/RSSHub","slug":"error-ad4ced","errorCode":null,"errorMessage":"非法域名！","messagePattern":"非法域名！","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"lib/routes/maccms/index.tsx","lineNumber":91,"sourceCode":"        type: '类别ID，不同采集站点有不同的类别规则和ID，默认为 0，代表全部类别',\n        size: '每次获取的数据条数，上限 100 条，默认 30 条',\n    },\n    name: '最新资源',\n    maintainers: ['hualiong'],\n    description: `::: tip\n每个采集站提供的影视类别 ID 是不同的，即参数中的 \\`type\\` 是不同的。**可以先访问一次站点提供的采集接口，然后从返回结果中的 \\`class\\` 字段中的 \\`type_id\\`获取相应的类别 ID**\n:::\n\n| 站名                | 域名                                             | 站名             | 域名                                               | 站名           | 域名                                            |\n| ------------------- | ------------------------------------------------ | ---------------- | -------------------------------------------------- | -------------- | ----------------------------------------------- |\n| 魔都资源网          | [moduzy.net](https://moduzy.net)                 | 华为吧影视资源站 | [hw8.live](https://hw8.live)                       | 360 资源站     | [360zy.com](https://360zy.com)                  |\n| jkun 爱坤联盟资源网 | [ikunzyapi.com](https://ikunzyapi.com)           | 奥斯卡资源站     | [aosikazy.com](https://aosikazy.com)               | 飞速资源采集网 | [www.feisuzyapi.com](http://www.feisuzyapi.com) |\n| 森林资源网          | [slapibf.com](https://slapibf.com)               | 天空资源采集网   | [api.tiankongapi.com](https://api.tiankongapi.com) | 百度云资源     | [api.apibdzy.com](https://api.apibdzy.com)      |\n| 红牛资源站          | [www.hongniuzy2.com](https://www.hongniuzy2.com) | 乐视资源网       | [leshiapi.com](https://leshiapi.com)               | 暴风资源       | [bfzyapi.com](https://bfzyapi.com)              |`,\n    handler: async (ctx) => {\n        const { domain, type = '0', size = '30' } = ctx.req.param();\n        if (!list.has(domain)) {\n            throw new Error('非法域名！');\n        }\n\n        const res = await ofetch<Result>(`https://${domain}/api.php/provide/vod`, {\n            parseResponse: JSON.parse,\n            query: { ac: 'detail', t: type, pagesize: Number.parseInt(size) > 100 ? 100 : size },\n        });\n\n        const items: DataItem[] = res.list.map((each) => ({\n            title: each.vod_name,\n            image: each.vod_pic,\n            link: `https://${domain}/vod/${each.vod_id}/`,\n            guid: each.vod_play_url?.match(/https:\\/\\/.+?\\.m3u8/g)?.at(-1),\n            pubDate: timezone(parseDate(each.vod_time, 'YYYY-MM-DD HH:mm:ss'), 8),\n            category: [each.type_name, ...each.vod_class!.split(',')],\n            description: render(each, `https://${domain}/vod/${each.vod_id}/`) + each.vod_content,\n        }));\n\n        return {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/maccms/index.tsx#L73-L109","documentation":"Thrown by the maccms (MacCMS aggregator) route when the :domain path parameter is not in the hardcoded allowlist Set at the bottom of the file (moduzy.net, hw8.live, 360zy.com, etc.). The Chinese message means 'illegal domain!'. This is a security/control measure: the route proxies /api.php/provide/vod from the supplied domain, so only vetted collection sites are allowed.","triggerScenarios":"Calling /maccms/example.com/... where example.com is not in the allowlist. Passing a domain with a trailing slash, port, protocol prefix, or www. that differs from the allowlist entry (e.g. 'www.moduzy.net' when the list has 'moduzy.net'). Passing a subdomain variant.","commonSituations":"User wants to add a new collection site but it is not in the allowlist. User includes 'https://' or a port. A previously-working domain was removed from the list. The user passes a domain that redirects to a different hostname.","solutions":["Use one of the documented allowlisted domains (see the table in the route description).","If you self-host and trust a new collection site, add its exact hostname string to the list Set at the end of lib/routes/maccms/index.tsx.","Ensure the domain has no protocol prefix, trailing slash, or port — match the exact string format in the Set.","Normalize input (strip protocol/www.) before the check if you want more lenient matching, but weigh the SSRF implications."],"exampleFix":"// before\nconst { domain, type = '0', size = '30' } = ctx.req.param();\nif (!list.has(domain)) throw new Error('非法域名！');\n\n// after — strip protocol/www and give a helpful message\nconst { domain: rawDomain, type = '0', size = '30' } = ctx.req.param();\nconst domain = rawDomain.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').replace(/\\/$/, '');\nif (!list.has(domain)) {\n    throw new InvalidParameterError(`Domain '${domain}' is not allowed. Supported: ${[...list].join(', ')}`);\n}","handlingStrategy":"validation","validationCode":"const list = new Set(['moduzy.net', 'hw8.live', /* ... */]);\nconst { domain: rawDomain } = ctx.req.param();\nconst domain = rawDomain.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').replace(/\\/$/, '').toLowerCase();\nif (!list.has(domain)) {\n    throw new InvalidParameterError(`Domain '${domain}' not allowed. Supported: ${[...list].join(', ')}`);\n}","typeGuard":"function isAllowedMaccmsDomain(d: string, allow: Set<string>): boolean {\n    const normalized = d.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').replace(/\\/$/, '').toLowerCase();\n    return allow.has(normalized);\n}","tryCatchPattern":null,"preventionTips":["Normalize the domain (strip protocol, www, trailing slash, lowercase) before the allowlist check.","Derive the route's documentation table from the same Set to avoid drift.","Throw InvalidParameterError (not generic Error) for unsupported domains so callers can distinguish bad input.","Weigh SSRF risk before adding new domains or enabling fuzzy matching."],"tags":["validation","domain-allowlist","maccms","ssrf-protection","parameter"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}