convos
convos copied to clipboard
CSP (Content-Security-Policy) Support
Describe the bug
Multiple.
Currently, with CSP, connecting to the server blocks things like inline code and evals. Requiring the flag usafe-inline and unsafe-eval. batman has already started working on removing inline JS.
Setting default-src (with flags other than outlining the allowed, recommended with nothing else set is 'self') blocks the external calls to gstatic and MaxCDN. Will post another comment outlining the proper use of this header when all is said and done.
Please reference https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy for full info on CSP.
To Reproduce Steps to reproduce the behavior:
- Have CSP enabled.
- Go to your servers address
- Lose your mind
Expected behavior Documentation should (in my opinion) enable this correctly by default, but if not, allow users the option to enable it and give them the correct header info to do so.
Environment:
- OS: All?
- Browser: All modern browsers
- Version: Modern?
Additional context Current working header below. Will update with future fixes in the comments of this issue.
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' object-src 'none' https;";
~~Fully working header, correct syntax this time.~~
~~Nginx (in the server {} block): add_header Content-Security-Policy "default-src 'none'; base-uri 'self';block-all-mixed-content; manifest-src 'self'; object-src 'none'; frame-ancestors 'none'; frame-src 'self'; img-src 'self' twemoji.maxcdn.com www.gravatar.com repository-images.githubusercontent.com https; connect-src 'self'; font-src 'self' fonts.gstatic.com https; style-src 'self' fonts.googleapis.com 'unsafe-inline' https; script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;~~
~~Apache (inside your VirtualHost): Header set Content-Security-Policy "default-src 'none'; base-uri 'self';block-all-mixed-content; manifest-src 'self'; object-src 'none'; frame-ancestors 'none'; frame-src 'self'; img-src 'self' twemoji.maxcdn.com www.gravatar.com repository-images.githubusercontent.com https; connect-src 'self'; font-src 'self' fonts.gstatic.com https; style-src 'self' fonts.googleapis.com 'unsafe-inline' https; script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;~~
Another reference https://content-security-policy.com/
Edit: update to be more secure and add githubusercontent.com
Okay, images are saved. Using img-src *; is fine, as its only loading images and the browser itself should handle issues there. However, the issue now comes up with the following error in console after a reload of the page The FetchEvent for "https://repository-images.githubusercontent.com/14822868/751ec900-ae2b-11ea-8fbb-1ee16400fa8f" resulted in a network error response: an object that was not a Response was passed to respondWith().
FetchEvent is the response (and that gave rise to your respondWith error). the bug is going to be on the request side. The service worker should use fetch with a Request() rather than a url string and then as part of the Request, specify the RequestDestination
https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith
This allows img-src *; to function correctly and load any image on the web, but not be blocked by content-src 'self';.
Edit: added some more info https://stackoverflow.com/questions/57872284/content-security-policy-violations-on-seemingly-valid-urls
Inline issue after 4.33 update https://imgur.com/oibXCGb Eval issue after 4.33 update https://imgur.com/aUZHWbq
Current working headers:
nginx: add_header Content-Security-Policy "default-src 'none'; base-uri 'self';block-all-mixed-content; manifest-src 'self'; object-src 'none'; frame-ancestors 'none'; frame-src 'self'; connect-src 'self' www.gravatar.com twemoji.maxcdn.com; img-src *; font-src 'self' fonts.gstatic.com https; style-src 'self' fonts.googleapis.com 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;
Apache: Header set Content-Security-Policy "default-src 'none'; base-uri 'self';block-all-mixed-content; manifest-src 'self'; object-src 'none'; frame-ancestors 'none'; frame-src 'self'; connect-src 'self' www.gravatar.com twemoji.maxcdn.com; img-src *; font-src 'self' fonts.gstatic.com https; style-src 'self' fonts.googleapis.com 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;

@wylel Would it be an idea to set these in either or res->header in mojo?
@stigtsp I will have to look at Mojo as im not familiar with it. i will update when I do.
I’m not entirely sure, but I think you can add it here: https://github.com/Nordaaker/convos/blob/00a95979a13762b502b07ff6d8d7257247ceda0c/lib/Convos.pm#L126
Let me know if that line does not make sense.
https://convos.chat/doc/develop#starting-the-application shows how to start a “live” development server. Note however that changes in the lib/ directory will cause Convos to reconnect all the IRC connections. Ask on freenode if you want a demo IRC server to test against that doesn’t mind a lot of reconnects.
I’m not entirely sure, but I think you can add it here:
I think this makes a lot of sense to do it there, not relying on nginx.
Another user had issues with CSP today, so I was wondering if I could add the header from https://github.com/Nordaaker/convos/issues/508#issuecomment-670849184 to Convos? Is there any risk involved in doing so?
I also wonder how difficult it would be to bundle the Google fonts... Maybe I should just do that. I still don't want to bundle the Twitter emojis though, since there's so many of them.
[..] Is there any risk involved in doing so?
Any breakage should be apparent in the console logs. I think it's nice to add some CSP rules. :)
Useful tool to visualize the rules: https://cspvalidator.org/#headerValue%5B%5D=default-src+'none'%3B+base-uri+'self'%3Bblock-all-mixed-content%3B+manifest-src+'self'%3B+object-src+'none'%3B+frame-ancestors+'none'%3B+frame-src+'self'%3B+connect-src+'self'+www.gravatar.com+twemoji.maxcdn.com%3B+img-src+*%3B+font-src+'self'+fonts.gstatic.com+https%3B+style-src+'self'+fonts.googleapis.com+'unsafe-inline'%3B+script-src+'self'+'unsafe-inline'+'unsafe-eval'%3B&strategy=intersection
Let me finally test it and see, if you haven't already. Been busy, sorry about that. Theoretically this should be fine.
fonts.googleapis.com and fonts.gstatic.com should not be required after 4c22cb9. I haven't built the new assets though, so just pulling "master" won't be enough to test it.
I wonder if we can use native emojis these days... Does anyone have an idea if the major Linux distros ship with emoji support now?
And I hope "unsafe-inline" and "unsafe-eval" for "script" is fixed already.
This can be added. Adding this for the sake of getting it later/tweaking before PR.
$c->res->headers->header('Content-Security-Policy', qq(default-src 'none'; base-uri 'self'; block-all-mixed-content; manifest-src 'self'; object-src 'none'; frame-ancestors 'none'; frame-src 'self'; connect-src 'self'; img-src *; font-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';));
Another good doc on potentially getting rid of the unsafe-inline with sha256. https://www.getastra.com/kb/knowledgebase/content-security-policy-all-you-need-to-know/
@jhthorsen as for the emojis, doing img-src *; is not that big of a deal, as long as nothing else requires them (like content-src or connect-src).
I think doing somehting like this is more readable and it's also easier to read the diff, in case we need to change one of the parameters.
package Convos;
...
$c->res->headers->content_security_policy($c->app->_content_security_policy);
...
sub _content_security_policy {
return join(
' ',
map { @$_ == 2 ? sprintf q(%s %s;), @$_ : "$_->[0];" } (
['default-src' => q('none')],
['base-uri' => q('self')],
['block-all-mixed-content'],
['manifest-src' => q('self')],
['object-src' => q('none')],
['frame-ancestors' => q('none')],
['frame-src' => q('self')],
['connect-src' => q('self')],
['img-src' => q(*)],
['font-src' => q('self' fonts.gstatic.com https)],
['style-src' => q('self' fonts.googleapis.com 'unsafe-inline')],
['script-src' => q('self' 'unsafe-inline' 'unsafe-eval')],
)
);
}
If possible, please sort the lines. Example: Would be nice if "object-src" could come after "img-src".
Here is another way to write the code:
sub _content_security_policy {
return join(' ',
map {"$_;"} q(block-all-mixed-content),
q(base-uri 'self'),
q(connect-src 'self'),
q(frame-ancestors 'none'),
q(manifest-src 'self'),
q(default-src 'none'),
q(font-src 'self' fonts.gstatic.com https),
q(frame-src 'self'),
q(img-src *),
q(object-src 'none'),
q(script-src 'self' 'unsafe-inline' 'unsafe-eval'),
q(style-src 'self' fonts.googleapis.com 'unsafe-inline'),
);
}
#508 will get merged one way or another, so I'm closing this issue.
#508 broke Convos, so I had to revert it. This needs to work with (at least)
- Embeds with images from third parties
- Twitter emojis
- Twitter iframe
I'll try to test it better next time before I make a release.
Which section broke emojis and embeds of images?
Should also have a look at https://digi.ninja/blog/svg_xss.php