Open triplecasquette opened 8 months ago
Thanks. we need a document for this
Had the same problem. Here is my not-expert description:
By default the configuration for CONTENT_SECURITY_POLICY is highly restrictive, and this is a feature, because it provides more security without effort. The default CSP Response Header is:
content-security-policy:
script-src 'self' 'unsafe-eval';
worker-src 'self' blob:;
child-src 'self' blob:;
img-src 'self' data: blob: https://raw.githubusercontent.com https://avatars.githubusercontent.com;media-src 'self';
connect-src 'self' https://* wss://*;
default-src 'self';
base-uri 'self';
font-src 'self' https: data:;
form-action 'self';
frame-ancestors 'self';
object-src 'none';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline'
This header is sent as an HTTP Response Header content-security-policy
for any Directus Admin page.
These directives define which domain/host a request can be sent to, by HTML elements present in the Directus Admin page. The CSP specs allows granular control, defining whitelist domains for every HTML element that can perform an HTTP request
<script src="..."/> => script-src
<iframe src="..."/> => frame-src
<object src="..."/> => object-src
<img src="..." /> => img-src
...
If a frame-src
directive is not defined, the fallback will be child-src
, but it's recommended to use frame-src
.
Like frame-src, every other directives, if not defined, will fallback to
child-src
as well, but THIS IS ONLY MY UNVERIFIED ASSUMPTION.
In Directus, to enable live preview mode, you go in Settings > Data Model > Select a Collection
and find an input where you defined the URL of the draft page. Directus will inject this URL as the src
attribute of the iframe
used for Live Preview.
Here is an example of that URL:
http://localhost:3000/draft/page
The domain entered here must be reachable by the CSP policy, so you must explicitly define it.
In this case you must define http://localhost:3000
.
You must use Environment Variables for that (or any equivalent based on your env, like docker-compose )
# .env
# frame-src
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="array:http://localhost:3000/"
# child-src
CONTENT_SECURITY_POLICY_DIRECTIVES__CHILD_SRC="array:http://localhost:3000/"
...
Directus uses helmet inside the Web Server so these env var will be passed to helmet.
This is how in an express app you define global helmet configration
app.use(
helmet({
contentSecurityPolicy: {
directives: {
"frame-src": ["'self'", "http://localhost:3000", "instagram.com"],
"script-src": ["'self'", "http://localhost:3000"],
},
},
})
);
Directus parse the env var, looks for the tail i.e. DIRECTIVES__FRAME_SRC
and inject the value in the helmet config.
# .env
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="array:'self',http://localhost:3000/,instagram.com" # array syntax 1
CONTENT_SECURITY_POLICY_DIRECTIVES__IMG_SRC="'self',http://localhost:3000/,instagram.com" # array syntax 2
# helmet config
app.use(
helmet({
contentSecurityPolicy: {
directives: {
"frame-src": ["'self'", "http://localhost:3000", "instagram.com"],
"img-src": ["'self'", "http://localhost:3000", "instagram.com"],
},
},
})
);
NOTE: 'self' refers the the actual page, and must be
'self'
and notself
. This is why it has double quotes.
I have tried above solution on Self Hosted Directus with Coolify and it did not work. I am not able to use Live Previews with NextJS. Is there a solution to this CSP iframing problem?
I have tried above solution on Self Hosted Directus with Coolify and it did not work. I am not able to use Live Previews with NextJS. Is there a solution to this CSP iframing problem?
You probably made a mistake somewhere. Or in the draft route on the next api or in your directus instance.
If both right then we need more to understand what happens.
Hope it helps :)
Probably. Could you help me out? I have tested the live preview on my browser it is working. On Directus, it does not work and gives me this console error:
Refused to frame 'https://www.mywebsite.com/' because it violates the following Content Security Policy directive: "child-src 'self' blob:". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
I have deployed with Coolify, so I have set below environment variables and restart the service there, but I still does not work:
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="array:'self',https://www.mywebsite.com/"
CONTENT_SECURITY_POLICY_DIRECTIVES__CHILD_SRC="array:'self',https://www.mywebsite.com/"
It seems that the directives you defined are not used.
To be sure, open the Dev Tools > Network tab and look at response header of the "document" request. You should find the content-security-policy header.
How did you define ENV vars?
If you used .ENV file and Docker compose you must tell Docker compose to use it
services:
directus:
image: directus
...
env_file:
- .env
This tells Docker Compose to load environment variables from a file named ".env" in the same directory as the compose file.
@tresorama Thanks, I just used the Coolify's dashboard to add the environment variables.
If you are saying the env variables are correct, than probably my problem is on Coolify's side. Actually I found an issue on their side, probably that is the reason.
If you are saying the env variables are correct, than probably my problem is on Coolify's side. Actually I found an issue on their side, probably that is the reason.
I never used coolify, but likely you guessed right.
You should understand if Directus docker container receive or not these env var, then fix that.
For example, for debugging if env vars defined in Coolify are effectively passed to Directus, you can add
SERVE_APP=false
to env vars and redeploy. If the env var is taken into consideration you shouldn't be able to use the Directus Admin
Definition:
SERVE_APP => Whether or not to serve the Data Studio. default: true
Probably. Could you help me out? I have tested the live preview on my browser it is working. On Directus, it does not work and gives me this console error:
Refused to frame 'https://www.mywebsite.com/' because it violates the following Content Security Policy directive: "child-src 'self' blob:". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
I have deployed with Coolify, so I have set below environment variables and restart the service there, but I still does not work:
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="array:'self',https://www.mywebsite.com/" CONTENT_SECURITY_POLICY_DIRECTIVES__CHILD_SRC="array:'self',https://www.mywebsite.com/"
Have you tried to only write :
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="'self' https: etc with space separated url
It works for me on docker and on my VPS no need to use array
In my case, the environment variable was completely missing due to my lack of understanding of how Coolify apply the variables. Details in this ticket: https://github.com/coollabsio/coolify/issues/4024
It now works for me, with the syntax mentioned above, it looks like this in my case:
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="'self' https://example.com https://test.example.com"
@lttr Worked! I also did not know that I had to edit the compose file. Thank you very much.
Describe the Request
I think it would be nice to add at least:
OR
because now (not some times ago) I had a CSP error with IFRAME.
So I spend hours to understand (not find it but I deducted it) that
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC="array:https://www.yourwebsite.com/"
In the .env file was the solution ^^
Maintainence Strategy
As often as the config option of CSP will change