mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
docs: CSP
This commit is contained in:
parent
ee250c0d83
commit
dc38eea060
1 changed files with 126 additions and 0 deletions
126
READMEs/README.content-security-policy.md
Normal file
126
READMEs/README.content-security-policy.md
Normal file
|
@ -0,0 +1,126 @@
|
|||
## Using Content Security Policy (CSP)
|
||||
|
||||
### What is it?
|
||||
|
||||
Modern browsers have recently implemented a new feature providing
|
||||
a sort of "selinux for your web page". If the server sends some
|
||||
new headers describing the security policy for the content, then
|
||||
the browser strictly enforces it.
|
||||
|
||||
### Why would we want to do that?
|
||||
|
||||
Scripting on webpages is pretty universal, sometimes the scripts
|
||||
come from third parties, and sometimes attackers find a way to
|
||||
inject scripts into the DOM, eg, through scripts in content.
|
||||
|
||||
CSP lets the origin server define what is legitimate for the page it
|
||||
served and everything else is denied.
|
||||
|
||||
The CSP for warmcat.com and libwebsockets.org looks like this,
|
||||
I removed a handful of whitelisted image sources like travis
|
||||
status etc for clarity...
|
||||
|
||||
```
|
||||
"content-security-policy": "default-src 'none'; img-src 'self' data:; script-src 'self'; font-src 'self'; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none';",
|
||||
"x-content-type-options": "nosniff",
|
||||
"x-xss-protection": "1; mode=block",
|
||||
"x-frame-options": "deny",
|
||||
"referrer-policy": "no-referrer"
|
||||
```
|
||||
|
||||
The result of this is the browser won't let the site content be iframed, and it
|
||||
will reject any inline styles or inline scripts. Fonts, css, ajax, ws and
|
||||
images are only allowed to come from 'self', ie, the server that served the
|
||||
page. You may inject your script, or deceptive styles: it won't run or be shown.
|
||||
|
||||
Because inline scripts are banned, the usual methods for XSS are dead;
|
||||
the attacker can't even load js from another server. So these rules
|
||||
provide a very significant increase in client security.
|
||||
|
||||
### Implications of strict CSP
|
||||
|
||||
Halfhearted CSP isn't worth much. The only useful approach is to start
|
||||
with `default-src 'none'` which disables everything, and then whitelist the
|
||||
minimum needed for the pages to operate.
|
||||
|
||||
"Minimum needed for the pages to operate" doesn't mean defeat the protections
|
||||
necessary so everything in the HTML can stay the same... it means adapt the
|
||||
pages to want the minimum and then enable the minimum.
|
||||
|
||||
#### Inline styles must die
|
||||
|
||||
All styling must go in one or more `.css` file served by the same server
|
||||
(preferably... you can whitelist other sources in the CSP if you have to).
|
||||
|
||||
Inline styles are no longer allowed (eg, "style='font-size:120%'" in the
|
||||
HTML)... they must be replaced by reference to one or more CSS class, which
|
||||
in this case includes "font-size:120%". This has always been the best
|
||||
practice anyway, and your pages will be cleaner and more maintainable.
|
||||
|
||||
#### Inline scripts must die
|
||||
|
||||
Inline scripts need to be placed in a `.js` file and loaded in the page head
|
||||
section, from the server that provided the page.
|
||||
|
||||
Then, any kind of inline script, yours or injected or whatever, will be
|
||||
completely rejected by the browser.
|
||||
|
||||
#### onXXX must be replaced by eventListener
|
||||
|
||||
Inline `onclick` or whatever are kinds of inline scripting and are banned.
|
||||
|
||||
Modern browsers have offered a different system called ["EventListener" for
|
||||
a while](https://developer.mozilla.org/en-US/docs/Web/API/EventListener) which allows binding of events to DOM elements in JS.
|
||||
|
||||
A bunch of different named events are possible to listen on, commonly the
|
||||
`.js` file will ask for one or both of
|
||||
|
||||
```
|
||||
window.addEventListener("load", function() {
|
||||
...
|
||||
}, false);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
...
|
||||
}, false);
|
||||
```
|
||||
|
||||
These give the JS a way to trigger when either everything on the page has
|
||||
been "loaded" or the DOM has been populated from the initial HTML. These
|
||||
can set up other event listeners on the DOM objects and aftwards the
|
||||
events will drive what happens on the page from user interaction and / or
|
||||
timers etc.
|
||||
|
||||
If you have `onclick` in your HTML today, you would replace it with an id
|
||||
for the HTML element, then eg in the DOMContentLoaded event listener,
|
||||
apply
|
||||
|
||||
```
|
||||
document.getElementById("my-id").addEventListener("click", function() {
|
||||
...
|
||||
}, false);
|
||||
```
|
||||
|
||||
ie the .js file becomes the only place with the "business logic" of the
|
||||
elements mentioned in the HTML, applied at runtime.
|
||||
|
||||
#### Do you really need external sources?
|
||||
|
||||
Do your scripts and fonts really need to come from external sources?
|
||||
If your caching policy is liberal, they are not actually that expensive
|
||||
to serve once and then the user is using his local copy for the next
|
||||
days.
|
||||
|
||||
Some external sources are marked as anti-privacy in modern browsers, meaning
|
||||
they track your users, in turn meaning if your site refers to them, you
|
||||
will lose your green padlock in the browser. If the content license allows
|
||||
it, hosting them on "self", ie, the same server that provided the HTML,
|
||||
will remove that problem.
|
||||
|
||||
Bringing in scripts from external sources is actually quite scary from the
|
||||
security perspective. If someone hacks the jquery site to serve a hostile
|
||||
payload in addition to the usual scripts, half the Internet will instantly
|
||||
become malicious. However if you serve it yourself, unless your server
|
||||
was specifically targeted you know it will continue to serve what you
|
||||
expect.
|
||||
|
Loading…
Add table
Reference in a new issue