DIYgod/RSSHub · error · ConfigNotFoundError

This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN

Error message

This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.

What it means

ConfigNotFoundError thrown by the biquge handler as a safety gate. The route accepts a user-supplied URL (lib/routes/biquge), which is an SSRF/unsafe-domain risk; the handler only allows hosts in the allowHost set unless the operator explicitly opts in via feature.allow_user_supply_unsafe_domain. This converts an unsafe request into a clear configuration instruction.

Source

Thrown at lib/routes/biquge/index.ts:67

路由默认返回最新 **1** 个章节,如有需要一次性获取多个章节,可在路由后指定 \`limit\` 参数。如上面的例子:订阅 [《大主宰》](http://www.biqu5200.net/0_7/) 并获取最新的 **10** 个章节。此时,路由为 [\`/biquge/http://www.biqu5200.net/0_7/?limit=10\`](https://rsshub.app/biquge/http://www.biqu5200.net/0_7/?limit=10)

需要注意的是,单次获取的所有章节更新时间统一设定为最新章节的更新时间。也就是说,获取最新的 **10** 个章节时,除了最新 **1** 个章节的更新时间是准确的(和网站一致的),其他 **9** 个章节的更新时间是不准确的。

另外,若设置获取章节数目过多,可能会触发网站反爬,导致路由不可用。
:::

::: warning
上方列举的网址可能部分不可用,这取决于该网站的维护者是否持续运营网站。请选择可以正常访问的网址,获取更新的前提是该网站可以正常访问。
:::`,
    handler,
};

async function handler(ctx) {
    const currentUrl = ctx.req.param('url');
    const rootUrl = currentUrl.split('/').slice(0, 3).join('/');
    if (!config.feature.allow_user_supply_unsafe_domain && !allowHost.has(new URL(rootUrl).hostname)) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    const response = await got(currentUrl, {
        responseType: 'buffer',
    });

    const isGBK = /charset="?'?gb/i.test(response.data.toString());
    const encoding = isGBK ? 'gbk' : 'utf-8';

    const $ = load(iconv.decode(response.data, encoding));
    const author = $('meta[property="og:novel:author"]').attr('content');
    const pubDate = timezone(parseDate($('meta[property="og:novel:update_time"]').attr('content')!), 8);

    let items = $('dl dd a')
        .toArray()
        .toReversed()
        .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 1)
        .map((item): DataItem => {

View on GitHub (pinned to bed535e087)

Solutions

  1. If you trust the domain, set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true in the environment and restart RSSHub.
  2. Otherwise use one of the hostnames already in the allowHost set (documented in the route description).
  3. To permanently add a trusted mirror, extend the allowHost set in the source and redeploy.

Example fix

# before: ALLOW_USER_supply_unsafe_domain unset -> error for non-allowlist host
# after
export ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true
Defensive patterns

Strategy: validation

Validate before calling

const hostname = new URL(rootUrl).hostname;
if (!config.feature.allow_user_supply_unsafe_domain && !allowHost.has(hostname)) {
    throw new ConfigNotFoundError(`Host ${hostname} not allowed; set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true`);
}

Type guard

const isAllowedHost = (hostname: string): boolean =>
    config.feature.allow_user_supply_unsafe_domain || allowHost.has(hostname);

Prevention

When it happens

Trigger: A request to /biquge/:url where the hostname extracted from the supplied URL is not in the allowHost allowlist, AND config.feature.allow_user_supply_unsafe_domain is not true.

Common situations: Operator points the route at a biquge mirror not in the built-in allowlist; deploying a newer RSSHub where the allowlist changed; intentionally wanting to track a private/new novel site.

Related errors


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