Integralność podzasobów (Subresource Integrity)
Subresource Integrity (SRI), w wolnym tłumaczeniu "integralność podzasobów", to funkcja bezpieczeństwa umożliwiająca przeglądarkom weryfikowanie, czy zasoby, które przechwytują (np. z CDN) docierają do nich bez nieporządanych zmian. Działanie takie jest możliwe dzięki używaniu hasha kryptograficznego, z którym przechwycony zasób musi być zgodny.
Notka: W celu weryfikacji integralności podzasobów danych przekazywanych ze źródła innego, niż dokument w którym są osadzane przeglądarki dodatkowo sprawdzają źródło poprzez międzyźródłowe udostępnianie zasobów, tzw. Cross-Origin Resource Sharing (CORS). Dzięki temu upewniają się, że pochodzenie (origin) oferujące dane zasoby pozwala na udostępnianie ich z innym, sprecyfizowanym originem.
Korzyści wynikające z "Subresource Integrity"
Używając Content Delivery Networks (CDNs) do hostowania plików, jak np. skrypty czy arkusze stylów, które są udostępnianie pośród licznych stron WWW można polepszyć wydajność strony i zachować przepustowość łącza. Jednakże, używając CDNów ryzykujemy, że jeśli atakujący przejmie kontrolę nad CDNem to może wprowadzić szkodliwą zawartość do plików na CDNie (lub zupełnie je zastąpić) i przez to potencjalnie może zaatakować wszystkie strony, które przechwytują pliki z tego CDNu.
"Subresource Integrity" pozwala na ograniczenie ryzyka ataków tego typu poprzez zapewnienie, że pliki które dana aplikacja, bądź dokument WWW przechwytują (m. in. z CDNu) zostały dostarczone bez udziału trzeciej strony, która "wzbogaciła" nasze dane o dodatkową treść oraz bez żadnych, jakichkolwiek innych zmian w przesyłanych plikach.
Używanie "Subresource Integrity"
Korzystanie z funkcji "Subresource Integrity" jest możliwe przez określenie hasha zakodowanego kryptograficznie w base64 zasobu (pliku), który przeglądarka ma przechwycić, z wartością atrybutu integrity
danego elementu <script> (en-US) or <link>
.
Wartość integrity
zaczyna się od co najmniej jednego stringu, przy czym każdy string zawiera prefiks wskazujący na konkretny algorytm hashowy (obecnie dozwolonymi prefiksami są sha256
, sha384
, i sha512
), następnie opatrzony myślnikiem i zakończony aktualnym hashem zakodowanym w base64.
Notka: Wartość integrity może zawierać liczne hashe oddzielone białymi znakami. Zasób zostanie załadowany, jeśli dopasuje się z jednym z tych hashów.
Przykładowy string integrity
z hashem sha384 zakodowanym w base64:
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
Więc oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
to część "hashowa", a prefiks sha384
wskazuje, że jest to hash sha384.
Notka: Część "hashowa" wartości integrity
jest, mówić ściśle, skrótem kryptograficznym formowanym przez zastosowanie określonych funkcji hashowych do danego outputu (np. skryptu lub arkuszu stylów). Zwykle używa się skrótu "hash" do określania skrótu kryptograficznego, więc w taki sposób to określenie jest używane w niniejszym artykule.
Narzędzia do generowania hashów SRI
Możesz generować hashe SRI z konsoli z openssl używając wywołania polecenia, jak:
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
lub z shasum używając wywołania polecenia, jak:
shasum -b -a 384 FILENAME.js | awk '{ print $1 }' | xxd -r -p | base64
Notka:
- Krok z
xxd
pobiera dane wyjściowe w postaci heksadecymalnej zshasum
i zamienia je na zapis binarny. - Krok z
awk
jest niezbędny, ponieważshasum
w danych wyjściowych przekazuje zahashowaną nazwę pliku doxxd
. Trzeba liczyć się z katastrofalnymi konsekwencjami, jeśli nazwa pliku zawiera znaki występujące w zapisie heksadecymalnym -xxd
odkoduje ten zapis i przekaże go dobase64
.
Warto wiedzieć, że dostępny na https://www.srihash.org/ SRI Hash Generator to narzędzie online umożliwiające generowanie hashy SRI.
Zasady bezpieczeństwa zawartości i Integralności podzasobów(Content Security Policy & Subresource Integrity)
Możesz skorzystać z Zasad bezpieczeństwa zawartości (Content Security Policy), by skonfigurować swój serwer, żeby wymuszał by określone typy plików wymagały stosowania Subresource Integrity. Aby to zrobić użyj dyrektywy require-sri-for (en-US) w swoim nagłówku CSP, np.:
Content-Security-Policy: require-sri-for script;
Dzięki temu zapisowi każda próba załadowania JavaScript powiedzie się jedynie, jeśli informacja o Subresource Integrity znajduje się na miejscu, a testy integralności zakończą się sukcesem.
Możesz również określić, że SRI powinno być stosowane podczas ładowania arkuszy stylów:
Content-Security-Policy: require-sri-for style;
Możesz również określić zarówno script
, jak i style
aby wymagać SRI przy obu typach plików.
Udostępnianie zasobów między źródłami i Integralności podzasobów (Cross-Origin Resource Sharing & Subresource Integrity)
Celem weryfikacji integralności podzasobów danych pochodzących z originu innego, niż dokument, w którym są osadzone, przeglądarki dodatkowo sprawdzają dane za pomocą CORS (Cross-Origin Resource Sharing). Upewniają się, że origin dostarczający dane pozwala na udostępnianie wnioskującemu originowi. Wtedy dane muszą zostać dostarczone z nagłówkiem Access-Control-Allow-Origin
, co pozwala na udostępnienie danych wnioskującemu originowi, np.:
Access-Control-Allow-Origin: *
Przykłady
W poniższych przykładach przyjmimy, że oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
to oczekiwany hash SHA-384 (skrót) określonego skryptu example-framework.js
i że istnieje kopia skryptu hostowana na https://example.com/example-framework.js
.
Subresource Integrity with the <script> element
Możesz użyć niniejszego elementu <script> (en-US), by nakazać przeglądarce, aby przed wywołaniem skryptu https://example.com/example-framework.js
najpierw porównała skrypt z oczekiwanym hashem i zweryfikowała, że są dopasowane.
<script src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
Notka: By dowiedzieć się więcej nt. zastosowania atrybutu crossorigin
sprawdź atrybuty ustawień CORS.
Jak przeglądarki radzą sobie z "Subresource Integrity"
Przeglądarki radzą sobie z SRI poprzez podjęcie poniższych działań:
-
Kiedy przeglądarka napotka element <script> (en-US) lub
<link>
z atrybutemintegrity
, przed wywołaniem skryptu lub przed zastosowaniem jakiegokolwiek arkusza stylów określonego przez element<link>
, przeglądarka musi najpierw porównać skrypt lub arkusz stylów do oczekiwanego hasha podanego w wartościintegrity
.Notka: Celem weryfikacji integralności podzasobów danych dostarczanych z originu innego, niż dokument, w którym zostały osadzone, przeglądarki dodatkowo sprawdzają dane poprzez stosowanie CORS, aby upewnić się, że origin dostarczający dane pozwala na udostępnianie ich z wnioskującym originem.
- Jeśli skrypt lub arkusz stylów nie pasuje do odpowiadającej mu wartości
integrity
, przeglądarka musi odmówić wywołania skryptu lub uwzględnienia arkusza stylów i zamiast tego musi zwrócić błąd sieciowy wskazujący, że nie powiodło się przechwycenie tego skryptu lub arkusza stylów.
Specyfikacje
Specyfikacja | Status | Komentarz |
---|---|---|
Subresource Integrity | Recommendation | |
Fetch | Living Standard |
Kompatybilność z przeglądarkami
BCD tables only load in the browser
Tabela kompatybilności na tej stronie jest generowana na podstawie danych strukturalnych. Jeśli chcesz ją współtworzyć, sprawdź https://github.com/mdn/browser-compat-data i wyślij nam pull requesta.
CSP: require-sri-for
No compatibility data found for http.headers.csp.require-sri-for
.
Check for problems with this page or contribute missing data to mdn/browser-compat-data.
Tabela kompatybilności na tej stronie jest generowana na podstawie danych strukturalnych. Jeśli chcesz ją współtworzyć, sprawdź https://github.com/mdn/browser-compat-data i wyślij nam pull requesta.
Zobacz również
- Zasady bezpieczeństwa zawartości (Content Security Policy)
- Content-Security-Policy (en-US)
- CDN, który Cię nie zXXSuje: Używanie Subresource Integrity
- Test na Subresource Integrity z W3C