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

Thrown as a ConfigNotFoundError by the javbus route when a user supplies a custom domain (via ?domain= or ?western_domain= query params) that is not in the hardcoded allowlist (javbus.com, javbus.org, javsee.icu, javsee.one) AND the server-level feature flag ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is not enabled. This is a deliberate security control to prevent SSRF — without it, any user could point RSSHub at an arbitrary domain.

Source

Thrown at lib/routes/javbus/index.tsx:84

        path: {
            description: 'Any path of list page on javbus',
        },
    },
    features: {
        nsfw: true,
    },
};

async function handler(ctx) {
    const isWestern = getSubPath(ctx).startsWith('/western');
    const domain = ctx.req.query('domain') ?? 'javbus.com';
    const westernDomain = ctx.req.query('western_domain') ?? 'javbus.org';

    const rootUrl = `https://www.${domain}`;
    const westernUrl = `https://www.${westernDomain}`;

    if (!config.feature.allow_user_supply_unsafe_domain && (!allowDomain.has(new URL(`https://${domain}/`).hostname) || !allowDomain.has(new URL(`https://${westernDomain}/`).hostname))) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    const currentUrl = `${isWestern ? westernUrl : rootUrl}${getSubPath(ctx)
        .replace(/^\/western/, '')
        .replace(/\/home/, '')}`;

    const headers = {
        'accept-language': 'zh-CN',
    };

    const response = await got({
        method: 'get',
        url: currentUrl,
        headers,
    });

    const $ = load(response.data);

View on GitHub (pinned to bed535e087)

Solutions

  1. If you operate the instance and trust the domain, set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true in your environment/config (only on private/self-hosted instances, never public ones).
  2. If you cannot change config, use one of the allowlisted domains: javbus.com, javbus.org, javsee.icu, javsee.one.
  3. To permanently support a new mirror safely, add its hostname to the allowDomain Set in lib/routes/javbus/index.tsx and rebuild.
  4. Do NOT enable this flag on public/shared instances — it allows arbitrary outbound requests (SSRF).

Example fix

// before (caller passes arbitrary domain)
const domain = ctx.req.query('domain') ?? 'javbus.com';

// after — restrict to allowlist before the config check even runs
const domain = ctx.req.query('domain') ?? 'javbus.com';
if (!allowDomain.has(new URL(`https://${domain}/`).hostname)) {
    throw new InvalidParameterError(`Domain ${domain} is not supported. Allowed: ${[...allowDomain].join(', ')}`);
}
Defensive patterns

Strategy: validation

Validate before calling

import { config } from '@/config';
const allowDomain = new Set(['javbus.com', 'javbus.org', 'javsee.icu', 'javsee.one']);

function resolveDomain(input: string | undefined, fallback: string): string {
    const d = input ?? fallback;
    const hostname = new URL(`https://${d}/`).hostname;
    if (!allowDomain.has(hostname) && !config.feature.allow_user_supply_unsafe_domain) {
        throw new ConfigNotFoundError(`Domain '${hostname}' not allowed. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true or use: ${[...allowDomain].join(', ')}`);
    }
    return hostname;
}

Try / catch

try {
    const domain = resolveDomain(ctx.req.query('domain'), 'javbus.com');
    // ...proceed
} catch (e) {
    if (e instanceof ConfigNotFoundError) {
        // surface config guidance to the operator
    }
    throw e;
}

Prevention

When it happens

Trigger: A request like /javbus?domain=mirror.example.com where mirror.example.com is not in the allowDomain set, and the deployment has not set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true. Also fires if only one of the two domains (domain vs western_domain) is non-allowlisted, since the check uses OR on the negation.

Common situations: A self-hoster wants to use a personal javbus mirror/proxy but has not set the env var. A user misunderstands the domain param as a free-form target. A shared/public RSSHub instance correctly blocks the request because enabling the flag on a public instance is an SSRF risk.

Related errors


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