Subresource Integrity (SRI) dla skryptów JavaScript
Napisał: Patryk Krawaczyński
21/10/2021 w Bezpieczeństwo Brak komentarzy. (artykuł nr 797, ilość słów: 486)
C
iekawą funkcjonalność przeglądarek podesłał Maciej Kofel ze Szkoły Security – SRI, czyli Subresource Intergrity, która umożliwia przeglądarkom weryfikację, czy pobierane przez nie zasoby (na przykład z zewnętrznych serwisów CDN) są dostarczane bez nieoczekiwanych manipulacji. Mechanizm ten działa na podstawie porównania skrótu kryptograficznego, który musi być zgodny z pobranym zasobem. Korzystanie z serwisów CDN do hostowania plików (skryptów JS, akruszy CSS) na swojej stronie może poprawić jej wydajność i oszczędzić przepustowość na serwerze. Jednak wiąże się również z ryzykiem, ponieważ jeśli atakujący przejmie kontrolę nad tym zasobem, może wstrzyknąć dowolną, złośliwą zawartość do plików (lub całkowicie zastąpić pliki), a tym samym potencjalnie zaatakować wszystkie witryny, które pobierają pliki z danego serwisu CDN.
Subresource Integrity pozwala ograniczyć ryzyko ataków, takich jak ten, zapewniając, że pliki pobierane przez przeglądarkę internetową zostały dostarczone bez wstrzykiwania przez stronę trzecią dodatkowej zawartości i bez jakichkolwiek innych zmian w tych plikach. Jeśli chcemy skorzystać z tej funkcji musimy określić zakodowany w base64 skrót kryptograficzny pliku, który ma pobrać przeglądarka. Jest on zawarty w atrybucie integrity
elementu <script>
lub <link>
. Wartość atrybutu integrity
zaczyna się od co najmniej jednego ciągu, przy czym każdy ciąg zawiera prefiks wskazujący konkretny algorytm haszowania (obecnie dozwolone są: sha256, sha384 i sha512), po którym następuje myślnik (“-“) i kończy się rzeczywistym haszem zakodowanym w base64:
sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=
Więc: 9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=
to hash, a: sha256-
określa algorytm skrótu. Hash jest, ściśle mówiąc skrótem kryptograficznym utworzonym przez zastosowanie określonej funkcji skrótu do jakiś danych wejściowych (tutaj pliku JS lub CSS). Ale często używa się słowa hasz / hash w znaczeniu skrótu kryptograficznego, więc do tego odnosi się to słowo w tym wpisie.
integrity
może zawierać wiele skrótów oddzielonych białymi znakami. Plik wówczas zostanie załadowany, jeśli pasuje do jednego z zdefiniowanych skrótów.
Kilka przykładów jak wygenerować taki skrót:
curl -s https://js.cdnek.com/jquery.min.js | openssl dgst -sha256 -binary \ | openssl enc -base64 -A ; echo "" cat style.css | openssl dgst -sha256 -binary | openssl base64 -A ; echo "" shasum -b -a 256 style.css | awk '{ print $1 }' | xxd -r -p | base64
Możemy skorzystać również z narzędzia, które zrobi to za nas. Tak stworzony i zakodowany skrót osadzamy w elemencie, który odwołuje się do zewnętrznych plików:
<script src="https://js.cdnek.com/jquery.min.js" integrity="sha256-jbQEGWgNcygk6SaNaOecK7qRztQesM83kULVjoVND1M=" crossorigin="anonymous"></script>
W przykładzie widzimy również użycie atrybutu crossorigin
. Odnosi się on do ustawień mechanizmu CORS, ponieważ po weryfikacji integralności zasobu udostępnionego z innego źródła przeglądarki dodatkowo sprawdzają zasób za pomocą wspomnianego mechanizmu Cross-Origin Resource Sharing, aby upewnić się, że źródło obsługujące żądanie o zasób umożliwia jego udostępnienie.
Więcej informacji: Javascript Security Checklist, Subresource Integrity, Atrybut: crossorigin