Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4]Content Security Policy issue of plugin-upload in strapi-4.0.0-beta.13 #11637

Closed
boeto opened this issue Nov 19, 2021 · 35 comments
Closed

[v4]Content Security Policy issue of plugin-upload in strapi-4.0.0-beta.13 #11637

boeto opened this issue Nov 19, 2021 · 35 comments
Labels
issue: bug Issue reporting a bug severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package source: core:upload Source is core/upload package status: confirmed Confirmed by a Strapi Team member or multiple community members

Comments

@boeto
Copy link

boeto commented Nov 19, 2021

Bug report

Describe the bug

[v4]Content Security Policy issue of plugin-upload in strapi-4.0.0-beta.13

Steps to reproduce the behavior

  1. Install and change the upload provider to aws-s3

  2. Upload an image and get the issue

Expected behavior

Should be able to see the picture. The same setting runs correctly in v3.

Screenshots

screenshot

Code snippets

// ./config/plugins.js

module.exports = ({ env }) => ({
  upload: {
    config: {
      provider: "aws-s3",
      providerOptions: {
        accessKeyId: env("AWS_ACCESS_KEY_ID"),
        secretAccessKey: env("AWS_ACCESS_SECRET"),
        region: env("AWS_REGION"),
        params: {
          Bucket: env("AWS_BUCKET"),
        },
      },
    },
  },
});

System

  • Node.js version: v14.17.6
  • YARN version: 1.22.17
  • Strapi version: 4.0.0-beta.13
  • Database: PostgreSQL 13
  • Operating system: macOS 10.15

Additional context

null

@boeto boeto changed the title Content Security Policy issue of plugin-upload in strapi-4.0.0-beta.13 [v4]Content Security Policy issue of plugin-upload in strapi-4.0.0-beta.13 Nov 19, 2021
@derrickmehaffy derrickmehaffy added severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package source: core:upload Source is core/upload package status: confirmed Confirmed by a Strapi Team member or multiple community members issue: bug Issue reporting a bug version: v4-Alpha/Beta labels Nov 19, 2021
@grzegorzbialy
Copy link

grzegorzbialy commented Nov 23, 2021

@boeto The internal middleware config change is not documented but I found out you can change default CSP settings middleware in config/middlewares.js like this:

module.exports = ({ env }) => [
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        directives: {
          'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
          'img-src': ["'self'", 'data:', 'cdn.jsdelivr.net', 'strapi.io', `${env('AWS_BUCKET')}.s3.${env('AWS_REGION')}.amazonaws.com`],
        },
      }
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::favicon',
  'strapi::public',
];

@derrickmehaffy
Copy link
Member

Provider examples will have an example config to show how to properly modify this. Closing as it's not a bug

@derrickmehaffy
Copy link
Member

This issue has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/strapi-v4-broken-image-even-when-the-images-link-works-cloudinary/14143/4

@derrickmehaffy
Copy link
Member

This issue has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/strapi-v4-override-csp/14157/2

@ludovicraymond
Copy link

Doesn't work for me for video assets.

It's ok for image type.

'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
 'img-src': ["'self'", 'blob:', 'data:', 'cdn.jsdelivr.net', 'strapi.io', `${env('AWS_BUCKET')}.s3.amazonaws.com`],
 'media-src': ["'self'", 'blob:', 'data:', 'cdn.jsdelivr.net', 'strapi.io', `${env('AWS_BUCKET')}.s3.amazonaws.com`],

any idea ?

@nsavinda
Copy link

image
https://dev.to/kevinadhiguna/what-is-cors-how-to-configure-cors-in-strapi-461b

@strapi-bot
Copy link

This issue has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/using-supabase-for-the-postgres-database/16762/2

@didiamuri
Copy link

Here is the configuration that worked for me, I spent 12 hours without finding a solution.

By removing the AWS_REGION, everything worked like a charm.

"@strapi/strapi": "4.1.0"

module.exports = ({ env }) => [
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          'media-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
];

@AvinashUtekar
Copy link

image
image

getting issue on image downloading

@derrickmehaffy
Copy link
Member

Here is the configuration that worked for me, I spent 12 hours without finding a solution.

By removing the AWS_REGION, everything worked like a charm.

"@strapi/strapi": "4.1.0"

module.exports = ({ env }) => [
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          'media-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
];

This only applies to us-east1 as all other AWS region S3 buckets NEED the region

@siemen-subbaiah
Copy link

For people wondering how to do the same with cloudinary :

module.exports = [
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
          'media-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];

@kwiat1990
Copy link

kwiat1990 commented May 23, 2022

For people wondering how to do the same with cloudinary :

module.exports = [
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
          'media-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];

And how to get other images inside Admin Panel to work? Right now only images from Clouidnary will be loaded, any other don't.

EDIT: for someone, who also look for a solution:

 ...
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com", // cloudinary images
            "lh3.googleusercontent.com", // google avatars
            "platform-lookaside.fbsbx.com", // facebook avatars
            "dl.airtable.com", // strapi marketplace
          ],
...

@carloshs94
Copy link

carloshs94 commented May 30, 2022

cant get it to work with scaleway. anyone did it??

{
  name: "strapi::security",
      config: {
        contentSecurityPolicy: {
          useDefaults: true,
          directives: {
            "connect-src": ["'self'", "https:"],
            'img-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.${env('AWS_REGION')}.${env('S3DOMAIN')}`],
            'media-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.${env('AWS_REGION')}.${env('S3DOMAIN')}`],
            upgradeInsecureRequests: null,
          },
        },
      },
  }

im getting this error in the console:

Refused to load the image 'https://bucket-name.s3.region.scw.cloud/thumbnail_logo_unir_e85e2ed42b.png?width=533&height=112' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: https://dl.airtable.com".

EDIT: FIXED, i had strapi::security duplicated at the end of the file, so it was being overwritten by the default one.

@Wwwolfgang
Copy link

I'm trying to make a upload on a Strapi project with a provider (default config, I guess). But al get it response is
Refused to connect to 'http://my-url/upload/' because it violates the following Content Security Policy directive: "connect-src 'self' https:".

With a Status Code 301

But the request url was https://my-url/upload
The request go through a nginx but why does it respond on http instead of https?
Everything else works in the admin panel, only the uploads dont.

@tranvuluan
Copy link

Here is the configuration that worked for me, I spent 12 hours without finding a solution.
By removing the AWS_REGION, everything worked like a charm.
"@strapi/strapi": "4.1.0"

module.exports = ({ env }) => [
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          'media-src': ["'self'", 'data:', 'blob:', `https://${env('AWS_BUCKET')}.s3.amazonaws.com`],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
];

This only applies to us-east1 as all other AWS region S3 buckets NEED the region

Wow thank you, I spent full day but can't fix, so lucky when I see your answer

@amityweb
Copy link

amityweb commented Sep 8, 2022

@carloshs94

EDIT: FIXED, i had strapi::security duplicated at the end of the file, so it was being overwritten by the default one.

Ah man you saved me hours. 'strapi::security', was already in the middlewares file when I added the 'strapi::security' code above it so it got cancelled out, and I never noticed until I read your update.

@timnolte
Copy link

One thing that should be made very clear by people looking here is that CORS errors and Content Security Policy are NOT the same thing. Those are different headers entirely. It is possibly that a Content Security Policy directive may introduce a CORS error by way of something being blocked, however, if you don't have any errors about specific items that were blocked because of specific Content Security Policies directives then that most likely means it's not a CSP(Content Security Policy) issue.

@WebShapedBiz
Copy link

I'm having exact same issue with Cloudflare R2 provider (https://www.npmjs.com/package/strapi-provider-upload-cloudflare-r2), with this error message:
Refused to load the image ... because it violates the following Content Security Policy directive: "img-src 'self' data: blob: https://dl.airtable.com".

Funny enough, when I remove https://dl.airtable.com from my middleware.js the error message stays the same.

@deivijt
Copy link

deivijt commented Dec 17, 2022

in this guide https://strapi.io/blog/how-to-set-up-amazon-s3-upload-provider-plugin-for-our-strapi-appoficial they keeps the REGION which is what causes the problem. :/

@mazwithwala
Copy link

In my case I had a sub directory on STORAGE_URL "/uploads" for both middleware.ts and plugins.ts so I just had to remove that on .env and everything was fine

@kepes
Copy link

kepes commented Jan 27, 2023

Based on Strapi docs I put midlewares.js into config/env/production folder. This way dev and prod environment separated.

This is my working midlewares.js content. I put AWS_REGION into the URL

module.exports = ({ env }) => [
  "strapi::errors",
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            `https://${env("AWS_BUCKET_NAME")}.s3.${env("AWS_REGION")}.amazonaws.com`,
          ],
          "media-src": [
            "'self'",
            "data:",
            "blob:",
            `https://${env("AWS_BUCKET_NAME")}.s3.${env("AWS_REGION")}.amazonaws.com`,
          ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  "strapi::cors",
  "strapi::poweredBy",
  "strapi::logger",
  "strapi::query",
  "strapi::body",
  "strapi::session",
  "strapi::favicon",
  "strapi::public",
];

In S3 bucket config I had to make my bucket public. I think the Strapi - Amazon AWS - Create the bucket doc is wrong because the bucket must be public, contrary to what the documentation says.

Based on S3 User guide I added a Bucket policy to my bucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::Bucket-Name/*"
            ]
        }
    ]
}

After configuration, you should check the images directly in a browser with the S3 Object URL. If everything went well, you can see the picture uploaded by Strapi. If the configuration failed and an error message is displayed, the Bucket is probably still not public.

Important!
According to the AWS user guide, creating a public S3 bucket is dangerous and should only be done if you are hosting a static website. In my opinion the uploaded images are part of a static website and in this situation it is acceptable, but I am not an AWS expert. Please consider not using the public S3 bucket if you are not comfortable with it!

Screenshots of my S3 Bucket config

bucket-01

bucket-02

bucket-03

Another beautiful day has passed to find this bug :)

@nikita-fuchs
Copy link

@carloshs94

EDIT: FIXED, i had strapi::security duplicated at the end of the file, so it was being overwritten by the default one.

Damn, that was my mistake, too, you saved me !

@nikantkamat
Copy link

Is there any same fix for the plugin "strapi-uploader-provider-do" because i am getting the same error

@strapi-bot
Copy link

This issue has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/content-security-policy-on-shared-hosting-with-two-nodejs-aps/29654/4

@dynamic-standard2
Copy link

If anyone has issues with the images of Strapi's Marketplace, add "market-assets.strapi.io" to the img-src and media-src directives, like this:

export default [
  'strapi::errors',
  'strapi::security',
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'", 
            "data:", 
            "blob:", 
            `https://${process.env.AWS_BUCKET}.s3.amazonaws.com`, 
            "dl.airtable.com", 
            "market-assets.strapi.io"
          ],
            "media-src": [
            "'self'", 
            "data:", 
            "blob:", 
            `https://${process.env.AWS_BUCKET}.s3.amazonaws.com`, 
            "dl.airtable.com", 
            "market-assets.strapi.io"
        ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];

@andersonstudioa
Copy link

I fixed changing the file config/middlewares.ts with CDN_URL

image

@brun0xff
Copy link

If anyone has issues with the images of Strapi's Marketplace, add "market-assets.strapi.io" to the img-src and media-src directives, like this:

export default [
  'strapi::errors',
  'strapi::security',
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'", 
            "data:", 
            "blob:", 
            `https://${process.env.AWS_BUCKET}.s3.amazonaws.com`, 
            "dl.airtable.com", 
            "market-assets.strapi.io"
          ],
            "media-src": [
            "'self'", 
            "data:", 
            "blob:", 
            `https://${process.env.AWS_BUCKET}.s3.amazonaws.com`, 
            "dl.airtable.com", 
            "market-assets.strapi.io"
        ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];

For god's sake thank you, you're awesome!

@LeNguyenMinhTuan
Copy link

I'm trying to make a upload on a Strapi project with a provider (default config, I guess). But al get it response is Refused to connect to 'http://my-url/upload/' because it violates the following Content Security Policy directive: "connect-src 'self' https:".

With a Status Code 301

But the request url was https://my-url/upload The request go through a nginx but why does it respond on http instead of https? Everything else works in the admin panel, only the uploads dont.

I'm stuck here too. Did you solve it ?

@jsphkhan
Copy link

jsphkhan commented Feb 5, 2024

I fixed changing the file config/middlewares.ts with CDN_URL

image

This is the solution to follow if anybody is using a CDN in front of S3 bucket. I was using a Cloudfront instance on top of AWS S3.

@Kamarhinanton
Copy link

Does enyone know, why after transferring data to prod, url is broken in reach text block? In media galery picture is ok.
image

@nikita-fuchs
Copy link

Does enyone know, why after transferring data to prod, url is broken in reach text block? In media galery picture is ok. image

Because your fileURL is pointing to localhost, which is not a thing of course when you deploy things somewhere else.

@Kamarhinanton
Copy link

Kamarhinanton commented Jul 4, 2024

How I can change this behaviour? On my local machine everything is ok with this text reach block.

@H3lltronik
Copy link

H3lltronik commented Jul 9, 2024

I haven't been able to fix it and don't know what to do.
My console logs this error:

Refused to load the image 'https://s3.us-east-1.amazonaws.com/my-bucket-stuff/thumbnail_1700242274671_05530326c8.jpeg?updatedAt=2024-07-09T05%3A26%3A13.053Z' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: https://s3.us-east-1.amazonaws.com/my-bucket-stuff".

This is my config/middlewares.js

module.exports = ({ env }) => [
  "strapi::errors",
  "strapi::cors",
  "strapi::poweredBy",
  "strapi::logger",
  "strapi::query",
  "strapi::body",
  "strapi::session",
  "strapi::favicon",
  "strapi::public",
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            `https://s3.${env("AWS_REGION")}.amazonaws.com/${env(
              "AWS_BUCKET_NAME"
            )}`,
          ],
          "media-src": [
            "'self'",
            "data:",
            "blob:",
            `https://s3.${env("AWS_REGION")}.amazonaws.com/${env(
              "AWS_BUCKET_NAME"
            )}`,
          ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];

I tried adding a wildcard like '/*' in the S3 URL but it doesn't work the only thing that has shown to work is to directly place the entire URL in the "img-src" array but that's obviously wrong.

Please, somebody help me, I've stuck here for days, it's the exact same start on both URLs and the wildcard seems to not be working, I'm so frustrated.

I'm running strapi 4.25.2

@javdevruent
Copy link

@H3lltronik have you ever fix this issue?

@DannyST89
Copy link

Thanks ,it works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue: bug Issue reporting a bug severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package source: core:upload Source is core/upload package status: confirmed Confirmed by a Strapi Team member or multiple community members
Projects
None yet
Development

No branches or pull requests