security: replace JSONP feeds with server-side proxies and harden links#95
Open
sudhirl-droid wants to merge 4 commits into
Open
security: replace JSONP feeds with server-side proxies and harden links#95sudhirl-droid wants to merge 4 commits into
sudhirl-droid wants to merge 4 commits into
Conversation
- Add Netlify Function proxies (news-feed, careers-feed) that fetch the Blogger feeds server-side and return plain JSON, eliminating browser-side JSONP and the associated remote-code-execution (XSS) risk. Inputs are validated/clamped and destinations are hard-coded (no SSRF). - Rewrite fetchNews/fetchOpenings to read JSON from the same-origin proxies; remove the JSONP loaders. - Add safeHttpUrl() and apply it to all feed-supplied links and image URLs to block javascript: and other non-http(s) schemes. - Add a DOMPurify hook forcing rel=noopener noreferrer on target=_blank links in sanitized job HTML. - Tighten CSP script-src to 'self' (drop blogger.com / news.maqsoftware.com); register functions dir; pin NODE_VERSION 20.
…rse merge for review)
Add Netlify-CDN-Cache-Control (s-maxage=300, durable) to news-feed and careers-feed so identical requests are served from the edge for 5 minutes. This cuts function invocations and upstream Blogger load, which also absorbs most abusive/repeat traffic before it reaches the function.
…rse merge for review)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security: replace JSONP feeds with server-side proxies + harden feed-derived content
Summary
Removes the browser-side JSONP loading of the Blogger news/careers feeds — a remote-code-execution/XSS vector — and replaces it with same-origin Netlify Function proxies that return plain JSON. Adds defense-in-depth around feed-supplied links/images and tightens the site CSP. Also adds durable edge caching so the proxies are cheap and abuse-resistant.
Why
The site previously injected
<script src="https://www.blogger.com/...">(JSONP) to load feeds, which executes whatever the remote server returns inside our origin. Any compromise of the feed host, or a MITM, becomes script execution on our site. This PR eliminates that class of risk.Changes
1. Server-side feed proxies (no more JSONP)
netlify/functions/news-feed.mjsandcareers-feed.mjsfetch the Blogger feeds server-side and return plain JSON. The browser only ever reads data.regionvalidated against an allow-list and integer params that are parsed + clamped.fetchNews/fetchOpeningsrewritten tofetch()the same-origin proxies; all JSONP loader code deleted.2. Link/URL hardening
safeHttpUrl()helper returns a URL only if it ishttp(s):, blockingjavascript:and other schemes arriving from feed data. Applied to all feed-supplied links and image URLs.afterSanitizeAttributeshook forcesrel="noopener noreferrer"on everytarget="_blank"link in sanitized job HTML (reverse-tabnabbing).3. CSP tightening
script-srcreduced from'self' https://www.blogger.com https://news.maqsoftware.com→'self'(possible now that JSONP is gone).4. Edge caching (cost / DoS hardening)
Netlify-CDN-Cache-Control: public, s-maxage=300, durable, so identical requests are served from Netlify's edge for 5 minutes — cutting function invocations and upstream Blogger load, and absorbing most repeat/abusive traffic before it reaches the function.5. Build config
netlify/functions(esbuild bundler) and pinNODE_VERSION = 20.Security impact
javascript:/ non-http(s) links & images from feedsscript-src 'self'Testing
tsc --noEmitandnpm run buildpass.feature_website-revamp— no conflicts.Notes / follow-ups (not in this PR)
AbortControllertimeout on the upstreamfetch(return504if Blogger hangs).Files changed
netlify/functions/news-feed.mjsnetlify/functions/careers-feed.mjsnetlify.tomlsrc/data/news.tssrc/data/careers.tssrc/lib/url.tssrc/lib/sanitizeHtml.ts