Content-Security-Policy
Meta-tag pozwala zmniejszyć ryzyko XSS ataków, pozwalając na określenie, gdzie zasoby mogą być ładowane z zapobiegając przeglądarkami ładowania danych z innych lokalizacjach. Utrudnia to atakującemu wstrzyknięcie złośliwego kodu do Twojej witryny.
Uderzyłem głową w ścianę z cegły, próbując zrozumieć, dlaczego popełniam błędy CSP jeden po drugim, i wydawało się, że nie było żadnych zwięzłych, jasnych instrukcji, jak to działa. Oto moja krótka próba wyjaśnienia niektórych punktów CSP, głównie skoncentrowana na rzeczach, które trudno mi rozwiązać.
Dla zwięzłości nie napiszę pełnego tagu w każdej próbce. Zamiast tego pokażę tylko content
właściwość, więc przykład, który mówi, content="default-src 'self'"
oznacza to:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. Jak zezwolić na wiele źródeł?
Możesz po prostu wymienić swoje źródła po dyrektywie jako listę oddzieloną spacjami:
content="default-src 'self' https://example.com/js/"
Zauważ, że nie ma cudzysłowu wokół parametrów innych niż specjalne , takich jak 'self'
. Ponadto :
po dyrektywie nie ma dwukropka ( ). Tylko dyrektywa, a następnie rozdzielona spacjami lista parametrów.
Wszystko poniżej określonych parametrów jest domyślnie dozwolone. Oznacza to, że w powyższym przykładzie byłyby to prawidłowe źródła:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
Te nie byłyby jednak ważne:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
^^ above the specified path
2. Jak korzystać z różnych dyrektyw, co one robią?
Najczęstsze dyrektywy to:
default-src
domyślne zasady ładowania javascript, obrazów, CSS, czcionek, żądań AJAX itp
script-src
określa prawidłowe źródła plików javascript
style-src
określa prawidłowe źródła plików css
img-src
określa prawidłowe źródła obrazów
connect-src
określa prawidłowe cele dla XMLHttpRequest (AJAX), WebSockets lub EventSource. Jeśli nastąpi próba połączenia z hostem, który nie jest tutaj dozwolony, przeglądarka wyemituje 400
błąd
Są inne, ale te są najbardziej potrzebne.
3. Jak korzystać z wielu dyrektyw?
Wszystkie dyrektywy definiuje się w ramach jednego metatagu, kończąc je średnikiem ( ;
):
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. Jak obsługiwać porty?
Wszystko oprócz domyślnych portów musi być jawnie dozwolone poprzez dodanie numeru portu lub gwiazdki po dozwolonej domenie:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
Powyższe spowodowałoby:
https://ajax.googleapis.com:123
^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
Jak wspomniałem, możesz również użyć gwiazdki, aby jawnie zezwolić na wszystkie porty:
content="default-src example.com:*"
5. Jak obsługiwać różne protokoły?
Domyślnie dozwolone są tylko standardowe protokoły. Na przykład, aby zezwolić na WebSockets ws://
, musisz zezwolić na to jawnie:
content="default-src 'self'; connect-src ws:; style-src 'self'"
^^^ web sockets are now allowed on all domains and ports
6. Jak zezwolić na protokół plików file://
?
Jeśli spróbujesz zdefiniować to jako takie, to nie zadziała. Zamiast tego zezwolisz na to za pomocą filesystem
parametru:
content="default-src filesystem"
7. Jak korzystać ze skryptów wbudowanych i definicji stylów?
O ile nie jest to wyraźnie dozwolone, nie można używać wbudowanych definicji stylów, kodu wewnątrz <script>
tagów ani właściwości tagów, takich jak onclick
. Pozwalacie im tak:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
Musisz także wyraźnie zezwolić na wstawianie obrazów zakodowanych w standardzie base64:
content="img-src data:"
8. Jak pozwolić eval()
?
Jestem pewien, że wiele osób powiedziałoby, że nie, ponieważ „ewolucja jest złem” i najprawdopodobniej przyczyną zbliżającego się końca świata. Ci ludzie by się mylili. Oczywiście, możesz zdecydowanie wykopać poważne dziury w bezpieczeństwie swojej witryny za pomocą eval, ale ma ona całkowicie uzasadnione przypadki użycia. Musisz tylko być mądrym w używaniu go. Pozwalasz na to tak:
content="script-src 'unsafe-eval'"
9. Co dokładnie 'self'
oznacza?
Możesz przez to 'self'
rozumieć localhost, lokalny system plików lub cokolwiek na tym samym hoście. To nic nie znaczy. Oznacza źródła, które mają ten sam schemat (protokół), ten sam host i ten sam port co plik, w którym zdefiniowana jest polityka treści. Czy udostępniasz swoją witrynę przez HTTP? Nie ma dla ciebie https, chyba że wyraźnie go zdefiniujesz.
Użyłem 'self'
w większości przykładów, ponieważ zwykle ma sens włączenie go, ale w żadnym wypadku nie jest to obowiązkowe. Zostaw to, jeśli nie potrzebujesz.
Ale poczekaj chwilę! Czy nie mogę po prostu content="default-src *"
z niego korzystać?
Nie. Oprócz oczywistych luk w zabezpieczeniach to również nie zadziała, jak można się spodziewać. Mimo że niektórzy doktorzy twierdzą, że na to pozwala cokolwiek, to nieprawda. Nie pozwala na wstawianie ani sprawdzanie poprawności, więc aby naprawdę, naprawdę uczynić twoją witrynę bardziej podatną na atak, możesz użyć tego:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... ale ufam, że nie.
Dalsza lektura:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy