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

Enable strict CSP headers to sandbox against any possible XSS #3632

Closed
cjdelisle opened this issue Apr 15, 2017 · 47 comments · Fixed by #12258
Closed

Enable strict CSP headers to sandbox against any possible XSS #3632

cjdelisle opened this issue Apr 15, 2017 · 47 comments · Fixed by #12258
Assignees
Labels
P1 S-Critical Prevents work, causes data loss and/or has no workaround Security T-Enhancement

Comments

@cjdelisle
Copy link

Modern browsers allow sending Content-Security-Policy headers and will prevent eval() or inline <script> tags as well as all of the variants of onload, onerror etc. which is a formidable barrier to XSS security breach.

This is an improvement suggestion which consists of removing any inline <script>, eval() or on* javascript (move these to remote loaded <script> and event handlers). Then begin sending CSP headers which (for script) allow 'self' and the urls of any content delivery networks which are used.

The benefit is peace of mind because modern browsers will disallow execution of XSS attack script so even if a vulnerability is discovered, the result the the vast majority of users is just an error in the console. Support: http://caniuse.com/#feat=contentsecuritypolicy

@lampholder
Copy link
Member

This is P3 because it's not on our immediate roadmap, but it seems like a solid idea.

I don't have a real idea for the level of effort or return on investment for Riot Web, though - I'll poke some people for some input.

@btittelbach
Copy link

You've probably all read the articles where people are now successfully looking into finding remote code execution bugs in Electron apps. https://statuscode.ch/2017/11/from-markdown-to-rce-in-atom/

Would be good to know riot.im is prepared for that.

@ara4n
Copy link
Member

ara4n commented Nov 23, 2017

We use CSP already in the media repository to stop content uploaded stuff containing XSS. Riot/Web itself isn't served with a CSP however, and unsure how Electron is configured. Bumping priority accordingly to investigate.

@ara4n ara4n added S-Critical Prevents work, causes data loss and/or has no workaround P1 and removed P3 labels Nov 23, 2017
@ara4n
Copy link
Member

ara4n commented Nov 23, 2017

marking as critical until proven otherwise

@rugk
Copy link
Contributor

rugk commented Feb 15, 2018

BTW to make sure each user of Riot uses it, I highly suggest to (also) use the in-HTML version of your CSP. (It's just a meta tag, so that is a nice enhancement)

I'll look into creating a CSP, which works with the current version. As always be aware, that CSPs are just additional security features, they can mitigate the attack, but they do not replace a real fix of an XSS attack or so, should one be found.

@rugk
Copy link
Contributor

rugk commented Feb 15, 2018

BTW it is not critical, but it is a very good (and highly suggested!) security enhancement.

@rugk
Copy link
Contributor

rugk commented Feb 15, 2018

E.g. a good step would be to do not use inline JS (i.e. don't include JS in HTML code). I think Riot works quite good with that, it just shows two errors in the console, but these seem to work:

Content Security Policy: Die Einstellungen der Seite haben das Laden einer Ressource auf self blockiert ("script-src 'self' 'unsafe-eval'"). Source: (function (ERROR) { const V8_STACK_....

And, of course, the window.vector_indexeddb_worker_script = 'bundles/070e2827d7275f44a591/indexeddb-worker.js'; which is included in script tags in the index.html.

@rugk
Copy link
Contributor

rugk commented Feb 15, 2018

Same with inline CSS. If you disable that it just breaks the whole styling.

The good news is, it works with a relatively strong JS prevention (script-src 'self')
The bad news, is, it uses object so I have to enable object-src. (#6165)

BTW a CSP checker can be found at https://csp-evaluator.withgoogle.com/.

@rugk
Copy link
Contributor

rugk commented Feb 20, 2018

Here is a suggestion for a CSP, which works for the current version:

Content-Security-Policy: "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' data:; connect-src *; font-src 'self'; media-src 'self'; child-src https://scalar.vector.im usercontent.riot.im blob:; form-action 'self'; object-src 'self'"

It only allows https://scalar.vector.im as the integrations server, but that can be adjusted. To limit the connections to one Matrix/Identity server, you would have to adjust connect-src. object-src is allowed because of #6165

@cjdelisle
Copy link
Author

IMO applying this rule goes a long way toward preventing XSS.

@ghost
Copy link

ghost commented Apr 12, 2018

'unsafe-eval' seems to be needed too, without it CSP reports: call to eval() or related function blocked by CSP. 1 bundle.js:80

Another error CSP reports is this:
Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src host 'unsafe-eval'”). Source: window.vector_indexeddb.... 1 host:46

Any idea how to fix this error?

This is the header with unsafe-eval enabled and only self hosted Identity server enabled that I use:
Content-Security-Policy: "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; img-src 'self' data:; connect-src 'self'; font-src 'self'; media-src 'self'; child-src https://usercontent.riot.im blob:; form-action 'self'; object-src 'self'"

@rugk
Copy link
Contributor

rugk commented Apr 12, 2018

However, that block does not result in problems, as far as I see. So maybe only something unimportant is blocked.

@ghost
Copy link

ghost commented Apr 12, 2018

I think it would be a good idea not to block parts of riot-web's code. Plus, I wonder why it's blocked in the first place. Scripts from that host should be allowed according to my CSP.

@rugk
Copy link
Contributor

rugk commented Apr 13, 2018

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src host 'unsafe-eval'”). Source: window.vector_indexeddb.... 1 host:46

This here is a message about blocking inline JS (not recommend but could be allowed with 'unsafe-inline'). The one from the indes.html. It#s really only a single line – and this line does not seem to be important, because it just seems to work without it.

Of course, I agree, it would be better if that is moved in a JS file and so not blocked by the CSP.

@t3chguy
Copy link
Member

t3chguy commented Apr 13, 2018

I'm not sure that can be moved to js trivially because webpack. As I understand it that line is important so that indexeddb operations happen in a worker. Indexeddb is needed for things like e2e.

@rugk
Copy link
Contributor

rugk commented Apr 13, 2018

No, e2e and such stuff worked for me without that line. Maybe it saved the database somehow else/used some fallback, or so…

@t3chguy
Copy link
Member

t3chguy commented Apr 13, 2018

Post the console of the app starting up, it'll say if it used a fallback storage

@rugk
Copy link
Contributor

rugk commented Apr 13, 2018

Did never look at that exactly, but that also does not matter.

@t3chguy
Copy link
Member

t3chguy commented Apr 13, 2018

If its using fallback storage then it DOES matter as the fallback has race conditions due to being synchronous and localStorage backed which causes e2e to fail in certain circumstances

@rugk
Copy link
Contributor

rugk commented Apr 13, 2018

So finally the JS should just be moved to a single file or so. Can't that hard… it's one line, after all.

@t3chguy
Copy link
Member

t3chguy commented Apr 13, 2018

Except half of that line isn't JavaScript and is instead a build tool generator placeholder for webpack.
<%= htmlWebpackPlugin.files.js[i] %>
and as you can see, its part of the htmlWebpackPlugin which suggests it'll only work in a html file

@rugk
Copy link
Contributor

rugk commented Apr 13, 2018

Ah, that's bad then.

@indolering
Copy link

In my tests everything worked without unsafe-eval. Anyway, it's of course only one example. Feel free to add whatever you want and remove parts to get stricter and stricter by time.

It sounds like it won't be mainlined without that piece of the codebase working. Could you add a build step that moves the inline script to an external file? Again, the important piece here is to get a working CSP into the codebase so we can improve things incrementally, let's not make this a blocking issue.

@rugk
Copy link
Contributor

rugk commented Jul 10, 2018

Ah, so the Riot devs should add it, sure… as you've mentioned how this can be done before.

@indolering
Copy link

Ah, so the Riot devs should add it, sure… as you've mentioned how this can be done before.

I'm basically asking if you will make the pull request or do I have to?

@rugk
Copy link
Contributor

rugk commented Jul 10, 2018

No, I'll not do a PR.

@Nadrieril
Copy link

Is there a recommended CSP string I can safely use when selfhosting riot ? And should this be documented somewhere ?

@rugk
Copy link
Contributor

rugk commented Feb 18, 2019

@Nadrieril I've added mine/one in here.

It should preferably not be documented, but actually tweaked (if needed) and merged into the code.

@Nadrieril
Copy link

Ok, thanks ! That'd be very cool indeed

@indolering
Copy link

It should preferably not be documented, but actually tweaked (if needed) and merged into the code.

I would document and unit test each rule* to make sure it hasn't been borked! Declarative specs count as code 😄.

*This is technically unit testing and might require a service like Sauce Labs (which has free accounts for F/OSS projects).

@indolering
Copy link

@rugk Did you ever get around to that PR?

@rugk
Copy link
Contributor

rugk commented Mar 26, 2019

As explained earlier no. Especially, because I don't know it is what the riot devs want. (and how strict it should be, testing etc.)

@532910
Copy link
Contributor

532910 commented Mar 26, 2019

@ara4n
Copy link
Member

ara4n commented Nov 13, 2019

riot.im/app now has a CSP on it. however, we have script-src: unsafe-inline due to the webpack issue mentioned above - need to fix this before we can close it up (and add it to riot-web as an meta tag)

@aaronraimist
Copy link
Collaborator

For the record the current CSP is, as of ^ is

default-src 'none';
style-src 'self' 'unsafe-inline';
script-src 'self' 'unsafe-eval' 'unsafe-inline' https://www.recaptcha.net https://www.gstatic.com;
img-src * blob: data:;
connect-src *;
font-src 'self';
media-src * blob: data:;
child-src * blob: data:;
form-action 'self';
object-src 'self';
manifest-src 'self'

@ara4n
Copy link
Member

ara4n commented Nov 27, 2019

...and we need to add the CSP as a meta tag or similar so that Electron picks it up.

@aaronraimist
Copy link
Collaborator

Related: #11610

@stoically
Copy link

stoically commented Feb 1, 2020

Had a quick glance why unsafe-eval currently (v1.5.8) is required and found 18 instances in the final bundle. It seems there are 13 instances of new Function which function as fallback if the environment isn't an actual browser, so for those dropping unsafe-eval would probably be fine (in the browser not sure about desktop). Then there are 5 instances of eval which come from Modernizer trying to detect es5, not sure what's the impact of that not working.

fwiw, I'm using riot web (Firefox) without unsafe-eval for a while now and haven't noticed any problems - and the only CSP related error I saw so far is the Modernizer one at startup.

@jryans jryans self-assigned this Feb 5, 2020
@jryans jryans assigned t3chguy and unassigned jryans Feb 5, 2020
@jryans
Copy link
Collaborator

jryans commented Feb 5, 2020

In addition to embedding the CSP as a meta tag in the app, we'd also like to remove unsafe-inline from script-src.

@t3chguy
Copy link
Member

t3chguy commented Feb 6, 2020

Splitting off a new issue to track getting rid of unsafe-eval which is currently required for WASM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P1 S-Critical Prevents work, causes data loss and/or has no workaround Security T-Enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.