Skip to content

fix(csp): allow blob: in script-src and img-src for client-side selfie - #1529

Merged
jung-thomas merged 1 commit into
mainfrom
fix/selfie-csp-blob
Aug 7, 2026
Merged

fix(csp): allow blob: in script-src and img-src for client-side selfie#1529
jung-thomas merged 1 commit into
mainfrom
fix/selfie-csp-blob

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Problem

The client-side "Selfie with an Advocate" tool at /devtoberfest/selfie/ (shipped in #1523) works locally but fails on the deployed DEV approuter with two symptoms Tom reported:

  1. "Couldn't remove the background — using your full photo."
  2. A broken image for the finished selfie.

Root cause (single)

The approuter CSP in approuter/xs-app.json forbids blob: URLs in two directives the pipeline depends on. It passes locally because the Hugo dev server has no strict CSP; the production approuter does.

Live Playwright console on DEV:

  • script-src: onnxruntime-web (the @imgly/background-removal WASM inference backend) bootstraps by creating a blob: module and dynamically importing it. With no blob: in script-src:

    Loading the script 'blob:…' violates CSP directive: "script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' …"
    → background removal failed: no available backend found
    

    → segmentation fails soft → "using your full photo" (Symptom 1).

  • img-src: compositing loads the photo via <img src=blob:> (Konva), and the final preview is <img :src=finalUrl> where finalUrl is a blob: URL. With no blob: in img-src:

    Loading the image 'blob:…' violates CSP directive: "img-src 'self' … data: …"
    → stage init failed
    

    → fallback path also renders a blob: <img> → broken image (Symptom 2).

Fix

Add blob: to script-src and img-src. One-line change (two tokens):

- script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' https://ui5.sap.com …
+ script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' blob: https://ui5.sap.com …
- img-src 'self' https://raw.githubusercontent.com … data: …
+ img-src 'self' blob: https://raw.githubusercontent.com … data: …

worker-src already allows blob:, so this is consistent with the existing policy, and it pairs with the wasm-unsafe-eval already present for WASM. The vendored imgly model/WASM assets already serve 200 — this is purely the CSP.

Verification

  • JSON validated (jq); security-headers.test.js assertions preserved (script-src still matches ui5.sap.com + consent.trustarc.com; connect-src matches user-consent-center.trustarc.com).
  • Post-deploy (Tom's feat: implement Admin UI (Fiori Elements + freestyle SAPUI5) #1 rule): verify live on DEV via the real browser — background removal completes with progress %, cutout composites onto the frame, final PNG renders and downloads. Deploy is a full mbt build (approuter change), from fresh origin/main in the primary tree.

Only one CSP file in the repo carries this header (app/admin-shell/webapp/xs-app.json has routes only). Shipped by tutorials-approuter (path: ../approuter in .deploy/mta.yaml).

The client-side 'Selfie with an Advocate' pipeline (#1512) fails on the
deployed approuter because its CSP forbids blob: URLs:

- script-src: onnxruntime-web (the @imgly/background-removal WASM backend)
  bootstraps by creating a blob: module and dynamically importing it.
  Without blob: in script-src the import is blocked -> 'no available
  backend found' -> segmentation fails soft -> 'Couldn't remove the
  background — using your full photo.'
- img-src: Konva/canvas loads the photo via <img src=blob:> and the final
  preview <img :src=finalUrl> is a blob: URL. Without blob: in img-src
  both are blocked -> broken final image.

worker-src already permits blob:, so this is consistent with existing
policy. Paired with the wasm-unsafe-eval already present. Preserves all
security-headers smoke-test assertions (ui5.sap.com, trustarc hosts).
@jung-thomas
jung-thomas merged commit 0353d1b into main Aug 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant