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

The bdys route lets users supply a custom mirror domain via the `domain` query param. If config.feature.allow_user_supply_unsafe_domain is false AND the supplied hostname is not in the static allowDomains set, it throws ConfigNotFoundError. This is a security control: user-supplied domains can be used for SSRF, so they must be explicitly whitelisted or globally opted into.

Source

Thrown at lib/routes/bdys/index.tsx:109

| ------ | ---- | ---- | ---- | ------ | ------ |

#### 影视排序

| 更新时间 | 豆瓣评分 |
| -------- | -------- |
| 0        | 1        |`,
};

async function handler(ctx) {
    const caty = ctx.req.param('caty') || 'all';
    const type = ctx.req.param('type') || 'all';
    const area = ctx.req.param('area') || 'all';
    const year = ctx.req.param('year') || 'all';
    const order = ctx.req.param('order') || '0';

    const site = ctx.req.query('domain') || 'bdys01.com';
    if (!config.feature.allow_user_supply_unsafe_domain && !allowDomains.has(new URL(`https://${site}`).hostname)) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    const rootUrl = `https://www.${site}`;
    const currentUrl = `${rootUrl}/s/${caty}?${type === 'all' ? '' : '&type=' + type}${area === 'all' ? '' : '&area=' + area}${year === 'all' ? '' : '&year=' + year}&order=${order}`;
    const response = await got({
        method: 'get',
        url: currentUrl,
    });

    const $ = load(response.data);

    let jsessionid = '';

    const list = $('.card-body .card a')
        .slice(0, 15)
        .toArray()
        .map((item): DataItem => {
            const $item = $(item);

View on GitHub (pinned to bed535e087)

Solutions

  1. Use the default domain (bdys01.com) by omitting ?domain=.
  2. If you trust the mirror, add it to allowDomains in the route file.
  3. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true in config when you accept the SSRF risk and control who can call the route.

Example fix

// before
RSSHUB_CONFIG_FEATURE_ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=false
// after
RSSHUB_CONFIG_FEATURE_ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true
Defensive patterns

Strategy: validation

Validate before calling

import config from '../../../lib/config';
function isDomainAllowed(host: string, allow: Set<string>): boolean {
  return allow.has(host) || !!config.feature.allow_user_supply_unsafe_domain;
}
const host = new URL(`https://${site}`).hostname;
if (!isDomainAllowed(host, allowDomains)) {
  throw new ConfigNotFoundError('Domain not allowed; set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true');
}

Type guard

const isAllowlistedDomain = (host: string, allow: Set<string>): boolean =>
  allow.has(host);

Try / catch

try {
  return await handler(ctx);
} catch (e) {
  if (e instanceof ConfigNotFoundError && /ALLOW_USER_SUPPLY_UNSAFE_DOMAIN/.test(e.message)) {
    ctx.throw(403, 'Custom domain not allowed');
  }
  throw e;
}

Prevention

When it happens

Trigger: A request sets ?domain=some-mirror.com that is not in allowDomains, while the ALLOW_USER_SUPPLY_UNSAFE_DOMAIN feature flag is not set to true in config.

Common situations: bdys moved to a new mirror and the user supplies it via ?domain=; an operator has not set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN and a request tries to use a non-allowlisted domain; SSRF-hardening kicks in by default.

Related errors


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