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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add CSP examples #13167

Merged
merged 2 commits into from Jun 20, 2018
Merged

doc: add CSP examples #13167

merged 2 commits into from Jun 20, 2018

Conversation

zeke
Copy link
Contributor

@zeke zeke commented Jun 6, 2018

This PR adds some examples of how to configure a Content Security Policy, using either an HTTP header or a <meta> tag.

馃崘 @liliakai

@zeke zeke requested review from felixrieseberg, a team and liliakai June 6, 2018 12:40
@zeke
Copy link
Contributor Author

zeke commented Jun 6, 2018

Would love to get input on a sensible default policy. default-src 'self' is probably too restrictive for most apps. But maybe the default example should be pretty strict?

@sindresorhus does your example in #12909 represent what you think are good defaults?

@MarshallOfSound MarshallOfSound self-requested a review June 6, 2018 20:26
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({responseHeaders: `default-src 'self'`})
})
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should point out that the best would be to start with default-src 'none'; and then allow what's needed. It's always better to include than exclude. Most will probably then end up with:

default-src 'none';
script-src 'self';
img-src 'self' data:;
style-src 'self';
font-src 'self';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a solid point, I agree with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to default-src 'none'

Copy link
Member

@felixrieseberg felixrieseberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can bikeshed which CSP we actually recommend a bit, but showing any kind of example is already helpful.

@MarshallOfSound MarshallOfSound merged commit 0802f82 into master Jun 20, 2018
@MarshallOfSound MarshallOfSound deleted the add-csp-examples branch June 20, 2018 00:36
const {session} = require('electron')

session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({responseHeaders: `default-src 'none'`})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is not correct. responseHeaders should be an object.

It also needs to be called on app.on('ready'), so for copy-pastable reasons, I think that should be included in the example too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃憤

@sindresorhus
Copy link
Contributor

I think you should also include these by in the example as they're not covered by default-src 'none';:

base-uri 'none';
form-action 'none';
frame-ancestors 'none';

I would also link to https://developers.google.com/web/fundamentals/security/csp/ which is another good resource on this topic.

@furrykef
Copy link

I don't find the current examples sufficient. For example, I have no idea where the "session.defaultSession.webRequest.onHeadersReceived" magic incantation is supposed to go. The "Writing Your First Electron App" page also does not even mention this issue despite the fact such an app will display a warning about CSP. Finally, since I haven't used CSP in any form at all before, let alone with Electron, it'd be nice to have a guide for what policies to set.

@justinmeiners
Copy link

Is onHeadersReceived called by file:// protocol URLs? If not, why would that be the recommended way of setting up CSP?

@Nantris
Copy link
Contributor

Nantris commented Sep 11, 2018

Can we possibly improve this example further? I and others have spent a lot of time trying to figure out how to get this working. None of the answers to this question on StackExchange seem to work for anyone but the submitter. https://stackoverflow.com/questions/51969512/define-csp-http-header-in-electron-app

I'm using a crazy preload script that injects the CSP currently. I've revisited this several times and never gotten the CSP to work via the header method.

I've tried inside and outside app.on('ready'), setting them for the default session and the specific window in question. Using object assign, and so many other attempts.

@smariel
Copy link

smariel commented Sep 15, 2018

Is onHeadersReceived called by file:// protocol URLs? If not, why would that be the recommended way of setting up CSP?

As @justinmeiners said, it seems that onHeadersReceived is not called by file:// protocol, unlike onResponseStarted. But onResponseStarted do not provides a callback object, so it is not possible to add CSP.

app.on('ready', () => {
  session.defaultSession.webRequest.onHeadersReceived((details,callback) => {
    console.log(`onHeadersReceived:\n${details.url}`);
  });
  session.defaultSession.webRequest.onResponseStarted((details) => {
    console.log(`onResponseStarted:\n${details.url}`);
  });
  ...
});

@busticated
Copy link

adding my voice to those asking for clearer docs and examples. the only thing i've been able to get working is this 馃憠 https://stackoverflow.com/a/52243138/579167

more problematically, while this approach appears to work as expected when i'm running in development (where my viewURL is an http url), when i run my packaged app (where my viewURL uses the file:// protocol), previously blocked content is rendered and visible (i'm setting img-src 'none' for testing so it's really easy to tell)

i've tried:

  • the example in the docs
  • setting extraHeaders in my mainWindow.loadURL() call (docs)
  • setting it via the <meta http-equiv="Content-Security-Policy"> tag

of those the meta tag actually works but doesn't support the frame-ancestors directive (and has a few other drawbacks unique to my use-case).

any help here would be very much appreciated 馃檹

cc @zeke @felixrieseberg

@MarshallOfSound
Copy link
Member

@busticated The file:// protocol does not support or recognize HTTP headers (because it is not an HTTP protocol). If you want to set a CSP on a file:// protocol file you need to use the meta tag strategy for setting a CSP.

@smariel
Copy link

smariel commented Sep 22, 2018

@MarshallOfSound thanks for this answer. So there is no way to set CSP in the main process if renderers are local files packaged in the application.

Do you know why details.headers and details.responseHeaders exist eaven with file:// protocol, when using onResponseStarted() ?

@justinmeiners
Copy link

@MarshallOfSound Thank you for this explanation. Since most Electron apps use local resources (file: protocol) shouldn't meta tag be the recommended way of doing CSP?

At the very least can we update the documentation to explain when to use "meta" tag instead of discouraging it?

@busticated
Copy link

thanks @MarshallOfSound 馃憤

it seems like that pattern - using http: for "development", file: for the package app - which i've seen fairly often out in the wild is likely to cause all sorts of weird edges cases. for example 馃憠 whatwg/html#3099

i realize this is somewhat off-topic but what's the guidance there? do most professional (馃檮) apps use file:// for everything (or vice-versa)? (looks like atom uses file://)

at the least, probably worth flagging in the docs along with calling out that the CSP headers should only be set for Content-Type: text/html (as well as application/xhtml+xml and application/xml i suppose) responses.

@Nantris
Copy link
Contributor

Nantris commented Sep 22, 2018

@MarshallOfSound I've submitted a docs PR to clarify this #14768

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants