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 by the javdb route's ProcessItems as a ConfigNotFoundError when the user-supplied `domain` query parameter is neither in the hardcoded allowDomain set ({javdb.com, javdb571.com, javdb36.com, javdb007.com, javdb521.com}) nor explicitly permitted via the ALLOW_USER_SUPPLY_UNSAFE_DOMAIN feature flag. It is an SSRF-guard: the route builds a Playwright URL from arbitrary user input, so only trusted domains are allowed by default.
Source
Thrown at lib/routes/javdb/utils.ts:17
import { load } from 'cheerio';
import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { DataItem } from '@/types';
import cache from '@/utils/cache';
import logger from '@/utils/logger';
import { parseDate } from '@/utils/parse-date';
import { getPlaywrightPage } from '@/utils/playwright';
const allowDomain = new Set(['javdb.com', 'javdb571.com', 'javdb36.com', 'javdb007.com', 'javdb521.com']);
const ProcessItems = async (ctx, currentUrl, title) => {
const domain = ctx.req.query('domain') ?? 'javdb.com';
const url = new URL(currentUrl, `https://${domain}`);
if (!config.feature.allow_user_supply_unsafe_domain && !allowDomain.has(url.hostname)) {
throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
}
const rootUrl = `https://${domain}`;
const { page, destroy, context } = await getPlaywrightPage(url.href, {
onBeforeLoad: async (page) => {
if (config.javdb.session) {
await page.context().addCookies([
{
name: '_jdb_session',
value: config.javdb.session,
domain,
path: '/',
},
]);
}
await page.route('**/*', (route) => {
const request = route.request();View on GitHub (pinned to bed535e087)
Solutions
- Use one of the whitelisted domains, e.g. /javdb?domain=javdb571.com
- If you run your own instance and trust the new mirror, add its hostname to allowDomain in lib/routes/javdb/utils.ts:9
- Alternatively set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true in the instance config (only when you understand the SSRF implications)
- Verify the hostname exactly — allowDomain.has uses exact match, so www.javdb.com is rejected even though javdb.com is allowed
Example fix
// before const allowDomain = new Set(['javdb.com', 'javdb571.com', 'javdb36.com']); // after — add the mirror you actually use const allowDomain = new Set(['javdb.com', 'javdb571.com', 'javdb36.com', 'javdb007.com', 'javdb521.com', 'javdb618.com']);
Defensive patterns
Strategy: validation
Validate before calling
import config from '@/utils/config';
const ALLOW_DOMAIN = new Set(['javdb.com', 'javdb571.com', 'javdb36.com', 'javdb007.com', 'javdb521.com']);
function assertAllowedDomain(domain: string | undefined): void {
const d = domain ?? 'javdb.com';
const host = new URL(currentUrl, `https://${d}`).hostname;
if (!config.feature.allow_user_supply_unsafe_domain && !ALLOW_DOMAIN.has(host)) {
throw new ConfigNotFoundError(`domain '${host}' not allowed`);
}
} Type guard
const ALLOW_DOMAIN = new Set(['javdb.com', 'javdb571.com', 'javdb36.com', 'javdb007.com', 'javdb521.com']);
function isAllowedJavdbDomain(domain: string): boolean {
return ALLOW_DOMAIN.has(domain);
} Try / catch
// Validate before invoking ProcessItems
if (!isAllowedJavdbDomain(domain) && !config.feature.allow_user_supply_unsafe_domain) {
return ctx.json({ error: 'domain not allowed' }, 400);
}
try { return await ProcessItems(ctx, currentUrl, title); }
catch (e) {
if (e instanceof ConfigNotFoundError) { /* user-facing 400 */ }
throw e;
} Prevention
- Whitelist exact hostnames only; document that subdomains are not auto-allowed
- Gate the feature flag behind an explicit operator decision (SSRF risk)
- Keep the allow-list in a shared constant so route + tests reference one source
- Reject before any network allocation (Playwright) on invalid domains
When it happens
Trigger: A request like /javdb?domain=evil.example.com (or any domain not in the allow-set) while config.feature.allow_user_supply_unsafe_domain is false/undefined. The new URL constructor accepts it, allowDomain.has() returns false, and the guard fires.
Common situations: Operator points the route at a javdb mirror not yet in the allow-list; self-hosters who have not set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true; typos in the domain query param; attempts to abuse the route as an open proxy.
Related errors
- This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN
- This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN
- This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN
- This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN
- This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/119cb487397a72d9.
Report an issue: GitHub.