Skip to content

1257: add CSP to scratch.html#1438

Open
DNR500 wants to merge 3 commits intomainfrom
1257-add-CSP-to-scratch-html
Open

1257: add CSP to scratch.html#1438
DNR500 wants to merge 3 commits intomainfrom
1257-add-CSP-to-scratch-html

Conversation

@DNR500
Copy link
Copy Markdown
Contributor

@DNR500 DNR500 commented Apr 16, 2026

issue: 1257

I’ve built the CSP to try to tap into the env variables that we use for deployments.

I’ve also tried to do some due diligence on the testing staging and staging environments in order to anticipate any problems - I did find something that was a begin pulled in on those environments that I’ve added a workaround for (see the comment below)

Local dev CSP output

This has to feature 'unsafe-eval' to allow the dev server to work

<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  base-uri 'none';
  object-src 'none';
  script-src 'self' 'unsafe-inline' 'unsafe-eval';
  style-src 'self' 'unsafe-inline';
  worker-src 'self' blob:;
  child-src 'self' blob:;
  connect-src 'self' http://localhost:3009 http://localhost:3011;
  img-src 'self' data: blob: http://localhost:3011;
  media-src 'self' blob: http://localhost:3011;
  font-src 'self' data: http://localhost:3011;
  form-action 'self';
  upgrade-insecure-requests;
">

Staging CSP output (take values from deploy-main in ci-cd.yml)


As the test environment uses editor-ui in staging that testing api needs to be listed on staging as well

<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  base-uri 'none';
  object-src 'none';
  script-src 'self' 'unsafe-inline';
  style-src 'self' 'unsafe-inline';
  worker-src 'self' blob:;
  child-src 'self' blob:;
  connect-src 'self' https://staging-editor-api.raspberrypi.org https://test-editor-api.raspberrypi.org https://staging-editor-static.raspberrypi.org;
  img-src 'self' data: blob: https://staging-editor-static.raspberrypi.org;
  media-src 'self' blob: https://staging-editor-static.raspberrypi.org;
  font-src 'self' data: https://staging-editor-static.raspberrypi.org;
  form-action 'self';
  upgrade-insecure-requests;
">

Production (take values from deploy-tag in ci-cd.yml)

<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  base-uri 'none';
  object-src 'none';
  script-src 'self' 'unsafe-inline';
  style-src 'self' 'unsafe-inline';
  worker-src 'self' blob:;
  child-src 'self' blob:;
  connect-src 'self' https://editor-api.raspberrypi.org https://editor-static.raspberrypi.org;
  img-src 'self' data: blob: https://editor-static.raspberrypi.org;
  media-src 'self' blob: https://editor-static.raspberrypi.org;
  font-src 'self' data: https://editor-static.raspberrypi.org;
  form-action 'self';
  upgrade-insecure-requests;
">

CSP violations for assets

Regarding current attempts to access images from https://cdn.assets.scratch.mit.edu/ - the set up above will result in CSP errors in the console. 




CDN-ASSET-SCRATCH_CSP

This should be short lived until we arrive at the solution for asset hosting - I don’t think this will stop anything else in the app working as a results. If we choose to host images on a different domain to the ones already stated we should be able to just add that domain to the img-src/media-src CSP.

Copilot AI review requested due to automatic review settings April 16, 2026 17:07
@DNR500 DNR500 temporarily deployed to previews/1438/merge April 16, 2026 17:07 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Content Security Policy (CSP) to scratch.html, with allowed origins derived from deployment environment variables via webpack template parameters, and updates CI/CD workflow inputs to support multiple API origins (staging + test).

Changes:

  • Load .env during webpack config evaluation and derive CSP-friendly origin strings (API + assets) for HTML template injection.
  • Add a CSP <meta http-equiv="Content-Security-Policy"> to src/scratch.html, including a dev-only unsafe-eval.
  • Extend deployment workflows to pass a CSP_API_MULTIPLE_ORIGINS value (and adjust chunk syncing include patterns).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
webpack.config.js Loads env for build-time templating; computes CSP origins and passes them into scratch.html template.
src/scratch.html Introduces a CSP meta tag with directives driven by env-derived origins and dev/prod differences.
.github/workflows/deploy.yml Adds a workflow input and env var for CSP_API_MULTIPLE_ORIGINS; modifies S3 sync include patterns.
.github/workflows/ci-cd.yml Supplies staging-specific csp_api_multiple_origins value to deployment workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread webpack.config.js Outdated
Comment thread webpack.config.js Outdated
Comment thread webpack.config.js Outdated
Comment thread src/scratch.html Outdated
Comment thread .github/workflows/deploy.yml Outdated
@DNR500 DNR500 temporarily deployed to previews/1438/merge April 16, 2026 17:30 — with GitHub Actions Inactive
run: |
aws s3 sync ./build/ s3://${{ secrets.AWS_S3_BUCKET }}/${{ needs.setup-environment.outputs.deploy_dir }} --endpoint ${{ secrets.AWS_ENDPOINT }} --progress-frequency 5
aws s3 sync ./build/chunks/ s3://${{ secrets.AWS_S3_BUCKET }}/chunks/ --endpoint ${{ secrets.AWS_ENDPOINT }} --exclude "*" --include "fetch-worker*" --progress-frequency 5
aws s3 sync ./build/chunks/ s3://${{ secrets.AWS_S3_BUCKET }}/chunks/ --endpoint ${{ secrets.AWS_ENDPOINT }} --exclude "*" --include "fetch-worker*" --include "mediapipe/**" --progress-frequency 5
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On testing and staging, but NOT on localhost, there is javascript being pulled in from the following CDN when trying to use the face sensing extension


https://cdn.jsdelivr.net/npm/@mediapipe/face_detection@0.4.1646425229/face_detection_solution_simd_wasm_bin.js


Whats happening in scratch

In scratch-editor there is an initial attempt to see if chunks exist for that extension

https://github.com/scratchfoundation/scratch-editor/blob/5283156f2c533d7c2783adc8622abed6d08002b9/packages/scratch-vm/src/extensions/scratch3_face_sensing/index.js#L94-L99

But a fallback is established if those chunks aren’t present locally

https://github.com/scratchfoundation/scratch-editor/blob/5283156f2c533d7c2783adc8622abed6d08002b9/packages/scratch-vm/src/extensions/scratch3_face_sensing/index.js#L101-L110

What we can do in editor-ui to get around this

It looks like the scratch-editor makes these available as part of the build - so they should exist in the dist folder
for scratch-gui In editor-ui, we are already copying the chunks from scratch-gui via web pack so this will include the face-sensing code

https://github.com/RaspberryPiFoundation/editor-ui/blob/825e69b72b26df8acc4a69b8960eee562368730d/webpack.config.js#L18-L21



https://github.com/RaspberryPiFoundation/editor-ui/blob/825e69b72b26df8acc4a69b8960eee562368730d/webpack.config.js#L246



So updating and adding this to our aws sync should get this working on all our environments - essentially we would then be hosting the code ourselves and the can request wouldn’t happen.



I’ve had to dig a little to understand the above - but I think this one liner should enable the face sensing extension without having to hit the CDN

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. Since we already have disabled some extensions that is also an option if this there are more problems with this extension or others.

@zetter-rpf
Copy link
Copy Markdown
Contributor

I saw Scratch doesn't work for the build for this PR - https://staging-editor-static.raspberrypi.org/branches/1438_merge/web-component.html

react-dom.production.min.js:2 Error: Error in Scratch GUI [location=https://staging-editor-static.raspberrypi.org/branches/1438_merge/scratch.html?project_id=cool-scratch.json&api_url=https%3A%2F%2Fstaging-editor-static.raspberrypi.org%2Fbranches%2F1438_merge&scratchMetadata=1&parent_origin=https%3A%2F%2Fstaging-editor-static.raspberrypi.org]: EvalError: Evaluating a string as JavaScript violates the following Content Security Policy directive because 'unsafe-eval' is not an allowed source of script: script-src 'self' 'unsafe-inline'".

@DNR500
Copy link
Copy Markdown
Contributor Author

DNR500 commented Apr 17, 2026

I saw Scratch doesn't work for the build for this PR - https://staging-editor-static.raspberrypi.org/branches/1438_merge/web-component.html

react-dom.production.min.js:2 Error: Error in Scratch GUI [location=https://staging-editor-static.raspberrypi.org/branches/1438_merge/scratch.html?project_id=cool-scratch.json&api_url=https%3A%2F%2Fstaging-editor-static.raspberrypi.org%2Fbranches%2F1438_merge&scratchMetadata=1&parent_origin=https%3A%2F%2Fstaging-editor-static.raspberrypi.org]: EvalError: Evaluating a string as JavaScript violates the following Content Security Policy directive because 'unsafe-eval' is not an allowed source of script: script-src 'self' 'unsafe-inline'".

I've had look at this - in our current Scratch GUI bundle/runtime, new Function(...) is executed, so unsafe-eval is currently required by the Scratch iframe CSP.

Adding unsafe-eval for all environment for now - I don't think there is an easy work around for this at the moment

Copy link
Copy Markdown
Contributor

@zetter-rpf zetter-rpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding unsafe-eval for all environment for now - I don't think there is an easy work around for this at the moment

Even with unsafe-eval this is really valuable - it will help us see in testing if we are depending on content from other domains.

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.

3 participants