DIYgod/RSSHub · warning · 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
18comic routes let the caller pick the source domain via a path parameter. Because the site rotates through many mirrors (some untrusted), the route only accepts a hard-coded allow-list of domains unless the operator explicitly opts in via config.feature.allow_user_supply_unsafe_domain. ConfigNotFoundError is thrown when an off-list domain is supplied and the flag is false.
Source
Thrown at lib/routes/18comic/utils.ts:22
import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { DataItem } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import md5 from '@/utils/md5';
import { parseDate } from '@/utils/parse-date';
import { renderDescription } from './templates/description';
const defaultDomain = 'jmcomic1.me';
// list of address: https://jmcomic2.bet
const allowDomain = new Set(['18comic.vip', '18comic.org', 'jmcomic.me', 'jmcomic1.me', 'jm-comic3.art', 'jm-comic.club', 'jm-comic2.ark']);
const apiDomain = 'www.cdnhth.cc';
const getRootUrl = (domain) => {
if (!config.feature.allow_user_supply_unsafe_domain && !allowDomain.has(domain)) {
throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
}
return `https://${domain}`;
};
const apiMapCategory = (category) => {
switch (category) {
case 'another':
return '其他漫畫';
case 'doujin':
return '同人';
case 'hanman':
return '韓漫';
case 'meiman':
return '美漫';
case 'short':
return '短篇';
case 'single':View on GitHub (pinned to bed535e087)
Solutions
- Use one of the allow-listed domains verbatim (see allowDomain in lib/routes/18comic/utils.ts).
- If you run your own instance and accept the SSRF/trust risk, set environment variable ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true.
- Open an issue / PR to add the new canonical domain to allowDomain so others benefit.
Example fix
# before (env) # nothing set, calling /18comic/<untrusted-mirror>/... # after ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true # OR keep default and call: /18comic/jmcomic1.me/...
Defensive patterns
Strategy: validation
Validate before calling
import { config } from '@/config';
const ALLOW_DOMAIN_18COMIC = new Set(['18comic.vip','18comic.org','jmcomic.me','jmcomic1.me','jm-comic3.art','jm-comic.club','jm-comic2.ark']);
function safe18comicDomain(domain) {
return ALLOW_DOMAIN_18COMIC.has(domain) || config.feature.allow_user_supply_unsafe_domain === true;
} Type guard
function isAllowed18comicDomain(d, allowAny): boolean {
return allowAny === true || ALLOW_DOMAIN_18COMIC.has(d);
} Prevention
- Resolve the mirror once and store it in config, not in ad-hoc URLs.
- Document the SSRF/trust implication of ALLOW_USER_SUPPLY_UNSAFE_DOMAIN before enabling it.
- Subscribe to the route's updates so allow-list additions propagate.
When it happens
Trigger: Calling any /18comic/... route with a `domain` parameter not in {18comic.vip, 18comic.org, jmcomic.me, jmcomic1.me, jm-comic3.art, jm-comic.club, jm-comic2.ark} while ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is unset/false.
Common situations: Hardcoding a mirror found on a forum that isn't yet in the allow-list; the site rotated domains and the allow-list is stale; running a self-hosted RSSHub with the safe default and pasting the newest mirror.
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/5aef06e365d16648.
Report an issue: GitHub.