UN-2238 [FIX] CSP: allow third-party origins found in report-only sweep - #2245
UN-2238 [FIX] CSP: allow third-party origins found in report-only sweep#2245Deepak-Kesavan wants to merge 1 commit into
Conversation
Sweep of the report-only policy on a live deployment (browsing + per-directive probes) turned up hosts the shipped bundle loads but no directive allows: - style-src/font-src: cdn.jsdelivr.net (Monaco CSS + codicon) - img-src: cdn.jsdelivr.net (emoji-datasource), ProductFruits, GTM, GA, reCAPTCHA assets, q.stripe.com - media-src: cdn.productfruits.com (new directive; default-src had no blob:) - connect-src: unpkg.com, api.productfruits.com, GA4 regional endpoints, reCAPTCHA api2, m.stripe.network - frame-src: googletagmanager ns.html, m.stripe.network ProductFruits' animations.css was the one violation observed in normal use; the rest belong to code paths and flows that were not exercised. Drops the bare `wss:` wildcard: socket.io connects to window.location.origin (GetStaticData getBaseUrl) and 'self' covers same-origin ws/wss per CSP3, verified with a ws:// probe against nginx serving this policy. Adds .claude/skills/csp-check so the policy can be re-checked against a build or a deployment when a frontend dependency changes.
Frontend Lint Report (Biome)✅ All checks passed! No linting or formatting issues found. |
|
|
| Filename | Overview |
|---|---|
| frontend/nginx.conf | Expands the report-only policy for known frontend resources and retains same-origin socket coverage through connect-src 'self'. |
| .claude/skills/csp-check/scripts/extract_policy.py | Adds a focused parser for the single quoted nginx CSP header and supports human-readable and JSON output. |
| .claude/skills/csp-check/scripts/probe.js | Adds directive-level browser probes with restrictive control requests and documented redirect interpretation. |
| .claude/skills/csp-check/scripts/scan_origins.py | Adds a deliberately coarse host-presence scan for local Vite output or deployed chunks, with directive-level validation delegated to the probe. |
| .claude/skills/csp-check/SKILL.md | Documents a layered static, probe, and real-usage procedure for validating the report-only CSP. |
| .gitignore | Un-ignores the new CSP-check skill directory so its files are tracked. |
Reviews (1): Last reviewed commit: "UN-2238 [FIX] CSP: allow third-party ori..." | Re-trigger Greptile
Unstract test resultsPer-group results
Critical paths
|



What
wss:wildcard fromconnect-src..claude/skills/csp-check— scripts + procedure for re-checking the policy against a build or a running deployment.Why
UN-2238. CSP is deployed in report-only mode; violations go to each user's browser console only, so gaps stay invisible until someone looks. This is that look, done against a live deployment (
v0.176.0).Two methods were used:
securitypolicyviolationacross landing, dashboard, prompt studio (incl. PDF viewer), API/ETL/task, logs, users, LLM settings, platform settings, profile, manual review. One violation fired in normal use: ProductFruits'animations.cssonstyle-src-elem.style-srccdn.jsdelivr.net,app.productfruits.comeditor.main.css; ProductFruits CSS (observed)font-srccdn.jsdelivr.netcodicon.ttfimg-srccdn.jsdelivr.net,app.productfruits.com,cdn.productfruits.com,www.googletagmanager.com,www.google-analytics.com,www.google.com/recaptcha/,www.gstatic.com/recaptcha/,q.stripe.comconnect-srcunpkg.com,api.productfruits.com,www.googletagmanager.com,region1.google-analytics.com,analytics.google.com,www.google.com/recaptcha/,m.stripe.networkframe-srcwww.googletagmanager.com,m.stripe.networkns.html; Stripe.jsmedia-src'self' blob: cdn.productfruits.comdefault-src 'self', noblob:)How
frontend/nginx.conf(theadd_header Content-Security-Policy-Report-Onlyvalue), plus a comment on thewss:removal..gitignoreun-ignores the new skill directory, matching the existing pattern for.claude/skills/worktree/.Can this PR break any existing features. If yes, please list possible items. If no, please explain why.
No. The header stays
-Report-Only, so nothing is blocked either way — the change only affects what gets reported. Every edit is additive except thewss:wildcard.That removal is the one item worth a second pair of eyes: socket.io connects to
window.location.origin(frontend/src/helpers/GetStaticData.js→getBaseUrl), and'self'covers same-origin ws/wss under CSP3. Verified by probingws://same-origin against a local nginx serving this exact policy — no violation reported. A deployment that terminates websockets on a different host or port would report (not block) it.Database Migrations
Env Config
Relevant Docs
.claude/skills/csp-check/SKILL.mdRelated Issues or PRs
Dependencies Versions
Notes on Testing
docker runofnginx:alpinewith thisnginx.conf: config accepted, header emitted verbatim.https://hooks.stripe.com/404-redirecting tohttps://stripe.com— CSP evaluates redirect targets, not a real gap.scan_origins.py --urlagainst the deployment: every external host referenced by the 248 bundle chunks is now covered by some directive.