I'm having the same problem (using S3/CloudFront) and it appears there is currently no way to set this up easily.

S3 has a whitelist of the headers permitted, and Content-Security-Policy is not on it. Whilst it is true you can use the prefixed x-amz-meta-Content-Security-Policy, this is unhelpful as there is no browser support for it.

There are two options I can see.

1) you can serve the html content from a webserver on an EC2 instance and set that up as another CloudFront origin. Not really a great solution.

2) include the CSP as a meta tag within your html document:

    <!doctype html>
    <html>
      <head>
        <meta http-equiv="Content-Security-Policy" content="default-src http://*.foobar.com 'self'">
...

This option is not as widely supported by browsers, but it appears to work with both Webkit and Firefox, so the current Chrome, Firefox, Safari (and IOS 7 Safari) seem to support it.

I chose 2 as it was the simpler/cheaper/faster solution and I hope AWS will add the CSP header in the future.

Answer from Ravenscar on Stack Overflow
Top answer
1 of 5
10

I'm having the same problem (using S3/CloudFront) and it appears there is currently no way to set this up easily.

S3 has a whitelist of the headers permitted, and Content-Security-Policy is not on it. Whilst it is true you can use the prefixed x-amz-meta-Content-Security-Policy, this is unhelpful as there is no browser support for it.

There are two options I can see.

1) you can serve the html content from a webserver on an EC2 instance and set that up as another CloudFront origin. Not really a great solution.

2) include the CSP as a meta tag within your html document:

    <!doctype html>
    <html>
      <head>
        <meta http-equiv="Content-Security-Policy" content="default-src http://*.foobar.com 'self'">
...

This option is not as widely supported by browsers, but it appears to work with both Webkit and Firefox, so the current Chrome, Firefox, Safari (and IOS 7 Safari) seem to support it.

I chose 2 as it was the simpler/cheaper/faster solution and I hope AWS will add the CSP header in the future.

2 of 5
6

S3/CloudFront takes any headers that the origin set and forward those to the client, but you can't set custom headers on you response directly.

You can use Lambda@Edge function that can inject security headers through CloudFront.

Here is how the process works: (reference aws blog)

  • Viewer navigates to website.
  • Before CloudFront serves content from the cache it will trigger any Lambda function associated with the Viewer Request trigger for that behavior.
  • CloudFront serves content from the cache if available, otherwise it goes to step 4.
  • Only after CloudFront cache ‘Miss’, Origin Request trigger is fired for that behavior.
  • S3 Origin returns content.
  • After content is returned from S3 but before being cached in CloudFront, Origin Response trigger is fired.
  • After content is cached in CloudFront, Viewer Response trigger is fired and is the final step before viewer receives content.
  • Viewer receives content.

Below is the blog from aws on how to do this step by step.

https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/

🌐
Simply Explained
simplyexplained.com › blog › implement content security policy with aws s3 and cloudfront
Implement Content Security Policy with AWS S3 and CloudFront | Simply Explained
May 1, 2018 - If we try to load something via HTTP, the browser will automatically upgrade the request to a secure HTTPS connection. And finally, we have report-uri which tells the browser to log violations of your policy to a service of your choosing. This is quite important, more on that later! After writing your CSP, add them to your HTTP headers like so: headers['content-security-policy'] = [{ key: 'Content-Security-Policy', value: "default-src 'self'; connect-src links.services.disqus.com www.google-analytics.com googleads.g.doubleclick.net static.doubleclick.net savjee.report-uri.com c.disquscdn.com d
🌐
AWS
docs.aws.amazon.com › aws app studio › user guide › builder documentation › viewing or updating your app's content security settings
Viewing or updating your app's content security settings - AWS App Studio
Also, to allow uploading objects to Amazon S3, you must edit the settings to allow the domains that can be uploaded to. The content security settings are used to configure Content Security Policy (CSP) headers in your application. CSP is a security standard that helps to secure your app from ...
🌐
Amazon Web Services
docs.aws.amazon.com › amazon simple storage service (s3) › user guide › access control in amazon s3 › identity and access management for amazon s3 › bucket policies for amazon s3 › examples of amazon s3 bucket policies
Examples of Amazon S3 bucket policies - Amazon Simple Storage Service
The aws:Referer condition key is offered only to allow customers to protect their digital content, such as content stored in Amazon S3, from being referenced on unauthorized third-party sites. For more information, see aws:Referer in the IAM User Guide. Suppose that you're trying to grant users access to a specific folder. If the IAM user and the S3 bucket belong to the same AWS account, then you can use an IAM policy to grant the user access to a specific bucket folder.
🌐
Medium
medium.com › swlh › content-security-policy-what-you-need-to-know-ffbce22336d6
Content Security Policy - What You Need to Know? | by Jainishshah | The Startup | Medium
December 15, 2020 - In a way, the attacker bypassed the “same-origin policy”. Since browsers will believe this to be legitimate it will run those scripts and we are DOOMED!!!!! . Millions of dollars in litigation depending on the type of data you deal with. For preventing this we need the browsers to be smart, but how will browsers know what is legitimate and what is not? You guessed it right, CSP. Instead of trusting everything received from the server, CSP creates a Content-Security-Policy HTTP header.
🌐
Medium
pushkar-sre.medium.com › implementing-cors-policies-and-content-security-policy-with-aws-cloudfront-a-comprehensive-guide-9a4c588db56c
Implementing CORS Policies and Content-Security-Policy with AWS CloudFront: A Comprehensive Guide | by Pushkar Joshi | Medium
August 5, 2024 - Content Security Policy (CSP) is a security mechanism that helps prevent various attacks like Cross-Site Scripting (XSS) and data injection attacks by specifying which sources of content are allowed to be loaded.
🌐
Rud
rud.is › home › collecting content security policy violation reports in s3 (‘effortlessly’/’freely’)
Collecting Content Security Policy Violation Reports in S3 ('Effortlessly'/'Freely') - rud.is
March 14, 2019 - In the previous post I tried to explain what Content Security Policies (CSPs) are and how to work with them in R. In case you didn’t RTFPost the TLDR is that CSPs give you control over what can be loaded along with your web content and can optionally be configured to generate a violation report […]
🌐
AWS re:Post
repost.aws › questions › QUYVva_suiTsSn4gH_004_sg › image-refused-to-load-due-to-content-security-policy-violation
Image refused to load due to content security policy violation | AWS re:Post
April 17, 2023 - Your request is violating Content security policy directive as you've mentioned it as ""frame-src 'self'". If you have index.html file, please change the meta tag as shown in the below link. For example you can modify it to - <meta http-equiv="Content-Security-Policy" content="script-src 'self' http://localhost:5000 'unsafe-inline' 'unsafe-eval';">
Find elsewhere
🌐
GitHub
github.com › mastodon › mastodon › issues › 28842
Images hosting in S3 are blocked by Content Security Policy (connect-src) · Issue #28842 · mastodon/mastodon
November 24, 2023 - Refused to connect to 'https://s3.example.com/mastodata/cache/accounts/avatars/111/796/170/184/288/825/original/98d6e6a9c04e870d.png' because it violates the following Content Security Policy directive: "connect-src 'self' data: blob: https://mastodon.example.com https://mastodon.example.com wss://mastodon.example.com".
Published   Jan 22, 2024
🌐
Mike Tabor
miketabor.com › how-to-add-security-headers-to-an-aws-s3-static-website
How to add Security Headers to an AWS S3 static website
The existing policy called “SecurityHeadersPolicy” is a great starting point for most any website: This policy should be a starting point and note this doesn’t set a Content-Security-Policy at all.
🌐
CodeBurst
codeburst.io › content-security-policy-with-amazon-cloudfront-part-1-5505feeaa75
Content Security Policy with Amazon CloudFront: Part 1 | by John Tucker | codeburst
December 8, 2018 - Did you know that you can ensure users never visit your site over HTTP accidentally? HTTP Strict Transport Security tells web browsers to only access your site over HTTPS in the future, even if the user attempts to visit over HTTP or clicks ...
🌐
Medium
htayyar.medium.com › content-security-policy-with-s3-cloudfront-cf7526889510
Content Security Policy with S3 + CloudFront | by Hasan Tayyar Beşik | Medium
February 13, 2018 - TLDR; Configuring CSP for a static web page that hosted on S3 and CDNed by CloudFront is an ugly process. Create new Lambda function in Virginia zone. This is important. Edge functions will only work in this region. Paste and modify this script to the function content · 'use strict'; exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; const headers = response.headers; headers['strict-transport-security'] = [{ key: 'Strict-Transport-Security', value: "max-age=31536000; includeSubdomains; preload" }];headers['content-security-policy'] = [{ key: 'Cont
🌐
Csplite
csplite.com › csp270
⁉ How to publish Content Security Policy headers in AWS S3, AWS Amplify and Amazon CloudFront - Lambda@Edge function, amplify.yml and customHttp.yml in Amazon Web Services
How to publish Content Security Policy headers in AWS S2, AWS Amplify and Amazon CloudFront - Lambda@Edge function, amplify.yml and customHttp.yml in Amazon Web Services
🌐
AWS re:Post
repost.aws › questions › QUvz6661t_QMCMvZQCQxIUsQ › resolving-content-security-policy-violation-for-image-loading-in-amazon-grafana
"Resolving Content Security Policy Violation for Image Loading in Amazon Grafana" | AWS re:Post
November 30, 2023 - Content Security Policy (CSP): A security feature that prevents unauthorized content from being loaded into a web application. Amazon Grafana: A managed service for visualizing metrics, logs, and traces.
🌐
Amazon Web Services
docs.aws.amazon.com › amazon simple storage service (s3) › user guide › security in amazon s3 › security best practices for amazon s3
Security best practices for Amazon S3 - Amazon Simple Storage Service
We recommend allowing only encrypted ... the aws:SecureTransport condition in your Amazon S3 bucket policies. For more information, see the example S3 bucket policy Managing access based on HTTP or HTTPS requests. In addition to denying HTTP requests, we recommend that you set Amazon CloudWatch alarms on tlsDetails.tlsVersion NOT EXISTS that alert you if HTTP access attempts are made on your content...
🌐
Reddit
reddit.com › r/aws › s3 static site w/cloudfront: csp problems
r/aws on Reddit: s3 static site w/cloudfront: CSP problems
January 5, 2024 -

I have been following an example from the cloudfront docs for setting up an s3 static site that uses cloudfront.

It works with the example content. But there's some problems when I upload my own static site content.

Basically, I have a static site generated by a tool called "quarto". It works if I deploy to a regular apache web server. But when I deploy the same content to s3+cloudfront, I see a bunch of CSP-related errors in the javascript console.

Visually, some fonts fall back to default values and also I see much of the javascript functionality doesn't work.

The types of errors I see are like this (it happens to be for math typesetting stuff, katex):

whatever-path/:1 Refused to load the script 'https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

I get 17 of them, all different, but all naming "Content Security Policy".

My very limited understanding is that is happening because I need to "whitelist" the hyperlinks of javascript libraries from other domains, for example, the one above: https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js

I see in the cloudfront console, under policies, there's a bunch of stuff related to origin request and response headers. It mentions CORS, which appears to be the same (or adjacent) concept to CSP. I haven't changed this from the default. I notice the example CF stack added some "security headers". Is this the place where I would need to make changes?

Is there a practical, straightforward approach for dealing with this? Or do I need to read and understand all aspects of website security before even attempting an s3 static site?

I should add that if I deploy the exact same static site to a lightsail instance I spun up that runs apache, it all works fine. The problem appears with s3+cloudfront.