koala73/worldmonitor · error · RssProxyPolicyError
URL protocol not allowed
Error message
URL protocol not allowed
What it means
Thrown by assertHttpProtocol() in the RSS proxy edge function when a feed URL's protocol is neither http: nor https: (e.g. ftp:, javascript:, file:, data:). This is a security guard preventing the proxy from being used as an SSRF vector. The error is an RssProxyPolicyError with HTTP status 400 (the default for the initial URL check).
Source
Thrown at api/rss-proxy.js:75
}),
}, timeoutMs);
}
// Allowlist + match predicate live in api/_rss-allowed-domain-match.js
// (shared with scripts/validate-rss-feeds.mjs --ci so the SSRF guard runs
// identically in the Edge handler and the build-time validator).
function isGoogleNewsFeedUrl(feedUrl) {
try {
return new URL(feedUrl).hostname === 'news.google.com';
} catch {
return false;
}
}
function assertHttpProtocol(url, message = 'URL protocol not allowed', status = 400) {
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
throw new RssProxyPolicyError(message, status);
}
}
function assertAllowedRedirect(url) {
assertHttpProtocol(url, 'Redirect protocol not allowed', 403);
// Apply the same www-normalization as the initial domain check so that
// canonical redirects (e.g. apex -> www) are not incorrectly rejected when
// only one form is in the allowlist.
if (!isAllowedDomain(url.hostname)) {
throw new RssProxyPolicyError('Redirect to disallowed domain');
}
}
export default async function handler(req, ctx) {
const corsHeaders = getCorsHeaders(req, 'GET, OPTIONS');
if (isDisallowedOrigin(req)) {
return jsonResponse({ error: 'Origin not allowed' }, 403, corsHeaders);View on GitHub (pinned to ffec79ac33)
Solutions
- Ensure the feed URL uses http:// or https:// — re-encode the url query parameter correctly.
- If the URL looks correct, check for hidden characters or encoding issues in the url query parameter (e.g. url=http%3A%2F%2F... vs a raw ftp://).
- For redirect-path instances (status 403, message 'Redirect protocol not allowed'), the initial URL was fine but a redirect Location header pointed to a non-HTTP URL — the source needs to fix its redirect.
- Validate the URL client-side before calling the proxy.
Example fix
// before GET /api/rss-proxy?url=ftp://feeds.example.com/news.xml // after GET /api/rss-proxy?url=https://feeds.example.com/news.xml
Defensive patterns
Strategy: validation
Validate before calling
// Validate the feed URL protocol before calling the RSS proxy
function isValidFeedUrl(urlStr) {
try {
const url = new URL(urlStr);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch {
return false;
}
}
if (!isValidFeedUrl(feedUrl)) {
throw new Error(`Feed URL must use http or https protocol: ${feedUrl}`);
} Type guard
function isRssProxyPolicyError(e: unknown): e is { status: number } & Error {
return e instanceof Error && (e as any).name === 'RssProxyPolicyError';
} Prevention
- Always validate feed URLs with new URL() and check protocol before passing to the proxy.
- Reject non-HTTP(S) protocols early in feed-source registration/config.
- URL-encode the url query parameter correctly to avoid protocol mangling.
When it happens
Trigger: Calling GET /api/rss-proxy?url=<feedUrl> where the feedUrl parses to a non-HTTP protocol — e.g. url=ftp://feeds.example.com/rss, url=javascript:alert(1), or a malformed URL that the URL constructor parses with an unexpected protocol. Also fires on the redirect path with a different message ('Redirect protocol not allowed', status 403).
Common situations: A feed URL in the source registry or user input that uses a non-standard protocol; an attempted SSRF payload targeting internal protocols (file:///etc/passwd); a copy-paste error introducing a typo in the URL scheme; a feed URL that was valid but got mangled by URL encoding.
Related errors
- Redirect to disallowed domain
- Webhook URL must not point to a metadata endpoint
- Webhook URL must not point to a private/local address
- serverUrl host is not allowed
- serverUrl hostname is blocked: ${hostname}
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/29002455166492ae.
Report an issue: GitHub.