DIYgod/RSSHub · warning · Error

非法域名!

Error message

非法域名!

What it means

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.

Solutions

  1. Use one of the documented allowlisted domains (see the table in the route description).
  2. 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.
  3. Ensure the domain has no protocol prefix, trailing slash, or port — match the exact string format in the Set.
  4. Normalize input (strip protocol/www.) before the check if you want more lenient matching, but weigh the SSRF implications.

Example fix

// before
const { domain, type = '0', size = '30' } = ctx.req.param();
if (!list.has(domain)) throw new Error('非法域名!');

// after — strip protocol/www and give a helpful message
const { domain: rawDomain, type = '0', size = '30' } = ctx.req.param();
const domain = rawDomain.replace(/^https?:\/\//, '').replace(/^www\./, '').replace(/\/$/, '');
if (!list.has(domain)) {
    throw new InvalidParameterError(`Domain '${domain}' is not allowed. Supported: ${[...list].join(', ')}`);
}
Defensive patterns

Strategy: validation

Validate before calling

const list = new Set(['moduzy.net', 'hw8.live', /* ... */]);
const { domain: rawDomain } = ctx.req.param();
const domain = rawDomain.replace(/^https?:\/\//, '').replace(/^www\./, '').replace(/\/$/, '').toLowerCase();
if (!list.has(domain)) {
    throw new InvalidParameterError(`Domain '${domain}' not allowed. Supported: ${[...list].join(', ')}`);
}

Type guard

function isAllowedMaccmsDomain(d: string, allow: Set<string>): boolean {
    const normalized = d.replace(/^https?:\/\//, '').replace(/^www\./, '').replace(/\/$/, '').toLowerCase();
    return allow.has(normalized);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/ad4ced55b3d91826. Report an issue: GitHub.

Appendix: source

Thrown at lib/routes/maccms/index.tsx:91

        type: '类别ID,不同采集站点有不同的类别规则和ID,默认为 0,代表全部类别',
        size: '每次获取的数据条数,上限 100 条,默认 30 条',
    },
    name: '最新资源',
    maintainers: ['hualiong'],
    description: `::: tip
每个采集站提供的影视类别 ID 是不同的,即参数中的 \`type\` 是不同的。**可以先访问一次站点提供的采集接口,然后从返回结果中的 \`class\` 字段中的 \`type_id\`获取相应的类别 ID**
:::

| 站名                | 域名                                             | 站名             | 域名                                               | 站名           | 域名                                            |
| ------------------- | ------------------------------------------------ | ---------------- | -------------------------------------------------- | -------------- | ----------------------------------------------- |
| 魔都资源网          | [moduzy.net](https://moduzy.net)                 | 华为吧影视资源站 | [hw8.live](https://hw8.live)                       | 360 资源站     | [360zy.com](https://360zy.com)                  |
| jkun 爱坤联盟资源网 | [ikunzyapi.com](https://ikunzyapi.com)           | 奥斯卡资源站     | [aosikazy.com](https://aosikazy.com)               | 飞速资源采集网 | [www.feisuzyapi.com](http://www.feisuzyapi.com) |
| 森林资源网          | [slapibf.com](https://slapibf.com)               | 天空资源采集网   | [api.tiankongapi.com](https://api.tiankongapi.com) | 百度云资源     | [api.apibdzy.com](https://api.apibdzy.com)      |
| 红牛资源站          | [www.hongniuzy2.com](https://www.hongniuzy2.com) | 乐视资源网       | [leshiapi.com](https://leshiapi.com)               | 暴风资源       | [bfzyapi.com](https://bfzyapi.com)              |`,
    handler: async (ctx) => {
        const { domain, type = '0', size = '30' } = ctx.req.param();
        if (!list.has(domain)) {
            throw new Error('非法域名!');
        }

        const res = await ofetch<Result>(`https://${domain}/api.php/provide/vod`, {
            parseResponse: JSON.parse,
            query: { ac: 'detail', t: type, pagesize: Number.parseInt(size) > 100 ? 100 : size },
        });

        const items: DataItem[] = res.list.map((each) => ({
            title: each.vod_name,
            image: each.vod_pic,
            link: `https://${domain}/vod/${each.vod_id}/`,
            guid: each.vod_play_url?.match(/https:\/\/.+?\.m3u8/g)?.at(-1),
            pubDate: timezone(parseDate(each.vod_time, 'YYYY-MM-DD HH:mm:ss'), 8),
            category: [each.type_name, ...each.vod_class!.split(',')],
            description: render(each, `https://${domain}/vod/${each.vod_id}/`) + each.vod_content,
        }));

        return {

View on GitHub (pinned to bed535e087)