Subresource Integrity (SRI) to standard bezpieczeństwa W3C, który pozwala określić hash kryptograficzny w tagach <script> i <link>, aby przeglądarka mogła zweryfikować, że załadowany plik odpowiada oczekiwaniom. Jeśli plik pod URL został zmodyfikowany, przechwycony lub zastąpiony (czy to przez atakującego, skompromitowany CDN, czy nawet przypadkową aktualizację), przeglądarka całkowicie blokuje wykonanie. SRI zostało ustandaryzowane w 2016 roku i jest wspierane przez każdą główną przeglądarkę. To jedno z najtańszych zabezpieczeń przed atakami na łańcuch dostaw na JavaScript stron trzecich, który w 2026 roku jest dominującym źródłem incydentów naruszeń na witrynach WordPress.
Jak wygląda hash SRI i jak go dodać?
Tag skryptu z włączonym SRI ma dwa dodatkowe atrybuty: integrity i crossorigin:
<script
src="https://cdn.example.com/jquery-3.7.1.min.js"
integrity="sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs"
crossorigin="anonymous">
</script>Wartość integrity to zakodowany w base64 hash kryptograficzny zawartości pliku, poprzedzony używanym algorytmem (sha256-, sha384- lub sha512-). SHA-384 to zalecany wybór w 2026 roku: dobra równowaga między bezpieczeństwem a długością hasha. SHA-512 też jest akceptowalne. SHA-256 nadal działa, ale uważane jest za najsłabsze z trzech; w porządku dla niekrytycznych zasobów, ale nie dla niczego wrażliwego pod względem bezpieczeństwa.
Gdy przeglądarka ładuje plik, oblicza jego hash i porównuje z wartością integrity. Jeśli hashe się zgadzają, skrypt działa. Jeśli różnią się choć o jeden bajt, przeglądarka odmawia wykonania i loguje błąd w konsoli.
Jakim atakom zapobiega Subresource Integrity?
SRI chroni konkretnie przed przypadkiem, gdy plik strony trzeciej zostaje zmodyfikowany między momentem, w którym zdecydowałeś mu zaufać, a momentem, w którym przeglądarka użytkownika faktycznie go ładuje. Trzy najbardziej istotne scenariusze dla witryn WordPress:
- Kompromitacja CDN. Jeśli atakujący włamie się do CDN (lub usługi strony trzeciej, której CDN używasz) i zmodyfikuje plik JavaScript, każda witryna osadzająca ten plik przez
<script src>nagle uruchomiłaby kod atakującego. SRI łapie to natychmiast: zmodyfikowany plik nie zgadza się z hashem, przeglądarka go blokuje. - Przejęcie konta u dostawcy strony trzeciej. Ktoś kompromituje konto analityki, widżetu czatu lub hostingu czcionek i wypycha złośliwą aktualizację skryptu, który osadziłeś. Bez SRI twoja witryna uruchamia złośliwą aktualizację przy każdym ładowaniu strony. Z SRI skrypt cicho zawodzi, dopóki nie zaktualizujesz hasha, co oznacza, dopóki osobiście nie zweryfikowałeś nowej wersji.
- Manipulacja na poziomie sieci. Atakujący man-in-the-middle w sieci korporacyjnej lub wrogim WiFi przepisuje plik JavaScript w trakcie tranzytu do użytkownika. HTTPS zapobiega temu w bezpośrednich połączeniach do twojego originu, ale skrypt strony trzeciej serwowany z kontrolowanej przez atakującego próby zatrucia DNS mógłby to obejść. SRI zapewnia kontrolę integralności end-to-end niezależnie od TLS.
Naruszenie British Airways z 2018 roku, w którym 380 000 klientów straciło dane płatnicze, miało miejsce, ponieważ atakujący zmodyfikował skrypt Modernizr strony trzeciej, który BA ładowało na stronie checkoutu. SRI na tym tagu skryptu zatrzymałoby atak w momencie załadowania zmodyfikowanego pliku. Podobne incydenty wciąż się zdarzają, z atakami typu Magecart na witrynach e-commerce jako najbardziej udokumentowaną kategorią.
Do jakich plików powinienem dodać SRI?
SRI jest dla plików stron trzecich ładowanych przez sieć. Liczą się trzy kategorie, w kolejności priorytetu:
- Procesy płatności, checkoutu i logowania. Każdy JavaScript działający na stronie, na której użytkownicy wprowadzają karty kredytowe, hasła lub inne wrażliwe dane, jest celem o najwyższym priorytecie. Skompromitowany skrypt na stronie checkoutu to najgorszy scenariusz. Jeśli twój checkout WooCommerce ładuje cokolwiek z CDN, każdy z tych skryptów powinien mieć SRI.
- Skrypty osadzone globalnie. Wszystko w
<head>lub blisko góry<body>, co działa na każdej stronie: tagi analityczne, czcionki, polyfills, jQuery z publicznego CDN. Te uruchamiają się, zanim użytkownik ma szansę zauważyć cokolwiek nie tak. - Skrypty CDN wstrzykiwane przez wtyczki. Wiele wtyczek WordPress (widżety czatu, A/B testing, piksele marketingowe) ładuje zdalny JavaScript. Te są pisane przez strony trzecie, którym domyślnie zaufałeś, i zwykle nie zawierają SRI domyślnie.
Z drugiej strony, nie dodawaj SRI do plików serwowanych z własnej domeny. Jeśli atakujący ma dostęp do modyfikacji plików na twoim serwerze originowym, może też zmodyfikować HTML, który deklaruje hash, więc SRI nie zapewnia prawdziwej ochrony. SRI błyszczy tylko dla zasobów cross-origin.
Jak wygenerować hash SRI dla skryptu strony trzeciej?
Trzy praktyczne metody:
- Użyj srihash.org. Narzędzie webowe. Wklej URL skryptu, otrzymaj kompletny tag
<script>z atrybutami integrity i crossorigin. Najszybsza droga do pojedynczych dodatków. - OpenSSL w linii poleceń.
curl -s https://cdn.example.com/file.js | openssl dgst -sha384 -binary | openssl base64 -Awyświetla hash base64, który poprzedzaszsha384-. Przydatne przy skryptach lub pracy z plikami lokalnie przed wdrożeniem. - Sprawdź dokumentację dostawcy. Główne CDN-y (cdnjs.com, jsDelivr) publikują hash SRI obok każdej wersji każdej biblioteki, którą hostują. Bootstrap, jQuery, Vue, React itp. wszystkie publikują zalecaną wartość integrity na swoich oficjalnych stronach getting-started. Kopiuj-wklej stamtąd.
Jedno zastrzeżenie: hash jest powiązany z dokładną zawartością bajtową pliku. Jeśli CDN serwuje inną wersję (ponieważ użyłeś URL jak jquery@3 zamiast jquery@3.7.1), hash nie będzie się zgadzał i skrypt zostanie zablokowany. Zawsze przypinaj do konkretnych wersji przy używaniu SRI.
Dlaczego atrybut crossorigin="anonymous" jest wymagany?
Atrybut crossorigin="anonymous" mówi przeglądarce, aby pobrała plik strony trzeciej używając CORS, bez wysyłania ciasteczek ani uwierzytelniania. Bez niego przeglądarka nie może odczytać ciała odpowiedzi pliku, aby obliczyć jego hash (osobliwość polityki same-origin), i weryfikacja SRI cicho zawodzi otwarto: skrypt uruchamia się bez sprawdzenia.
To najczęstszy błąd SRI. Ludzie dodają integrity, ale zapominają crossorigin, a potem zakładają, że ich konfiguracja działa, ponieważ skrypt nadal się ładuje. Bez obu atrybutów nie masz prawdziwej ochrony. Aby zweryfikować: otwórz DevTools, zakładkę Network, kliknij skrypt, spójrz na odpowiedź. Jeśli CDN obsługuje CORS (zasadniczo wszystkie nowoczesne publiczne CDN-y obsługują), zobaczysz Access-Control-Allow-Origin: * w nagłówkach odpowiedzi. Bez tego nagłówka SRI w ogóle nie może działać na tym zasobie.
Jak dodać SRI w WordPressie?
Trzy scenariusze w zależności od tego, jak skrypty trafiają do twoich stron:
Scenariusz 1: skrypty kolejkowane przez WordPress (motyw lub wtyczka)
Rdzeń WordPress obsługuje SRI przez filtr script_loader_tag. Dodaj do functions.php twojego motywu podrzędnego lub do małej wtyczki mu-plugin:
add_filter('script_loader_tag', function ($tag, $handle, $src) {
$sri_hashes = [
'jquery' => 'sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs',
'bootstrap' => 'sha384-...twoj-hash-tutaj...',
];
if (isset($sri_hashes[$handle]) && strpos($src, '://') !== false && strpos($src, home_url()) === false) {
$tag = str_replace(
' src=',
' integrity="' . $sri_hashes[$handle] . '" crossorigin="anonymous" src=',
$tag
);
}
return $tag;
}, 10, 3);Dostosuj nazwy handle i hashe, aby pasowały do twoich skryptów. Sprawdzenia strpos zapewniają, że SRI jest stosowane tylko do skryptów ładowanych z zewnętrznych domen, nie twoich.
Scenariusz 2: skrypty wpisane na sztywno w szablonach motywu
Jeśli motyw bezpośrednio wyświetla tagi <script src="https://..."> w header.php lub gdzie indziej, edytuj te tagi bezpośrednio, aby dodać atrybuty integrity i crossorigin. Odzwierciedl to w swoim motywie podrzędnym, aby przetrwać aktualizacje motywu nadrzędnego.
Scenariusz 3: skrypty wstrzykiwane przez JavaScript lub wtyczki stron trzecich w czasie wykonania
Widżety czatu, narzędzia A/B testing i menedżery tagów często wstrzykują tagi skryptu dynamicznie. SRI nadal działa w tym przypadku: dynamicznie utworzony element <script> musi ustawić właściwości integrity i crossOrigin, zanim skrypt zostanie dołączony do DOM. Większość wersji enterprise tych narzędzi to obsługuje przez konfigurację; darmowe poziomy zwykle nie. Dla niezarządzanych wstrzyknięć stron trzecich praktyczny fallback to Content Security Policy z require-sri-for script (wciąż w wersji roboczej) lub po prostu staranny audyt.
Jakie jest obciążenie utrzymania SRI?
To jest uczciwy trade-off. SRI to kompromis między bezpieczeństwem a wygodą. Za każdym razem, gdy biblioteka upstream się aktualizuje, hash się zmienia, twój skrypt pęka, i musisz zaktualizować hash. Dla stabilnej witryny, która przypina wersje i rzadko je aktualizuje, to zadanie raz na kwartał. Dla witryny używającej jquery@latest lub polegającej na auto-aktualizujących się CDN-ach, SRI to ciągłe źródło pęknięć.
Trzy wzorce, które czynią utrzymanie SRI zarządzalnym:
- Przypinaj do konkretnych wersji, nie "latest". URL jak
https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js, niejquery@latest. Hash pozostaje wtedy stabilny, dopóki celowo nie zaktualizujesz. - Używaj CDN, który publikuje hashe. cdnjs i jsDelivr oba publikują hash SRI dla każdego pliku. Aktualizacja hasha przy aktualizacji to zadanie 30-sekundowe.
- Samodzielnie hostuj krytyczne biblioteki. Gdy raz samodzielnie hostujesz (co powinieneś rozważyć z powodów RODO i tak, zobacz dyskusję o Google Fonts), SRI staje się nieistotne dla tego skryptu. SRI jest dla przypadków, w których nie możesz samodzielnie hostować. Dla analityki, czcionek, bibliotek używanych na jednej stronie, samodzielny hosting jest często lepszą odpowiedzią.
Częste błędy
- Zapomnienie
crossorigin="anonymous". Skrypt nadal się ładuje, ale nie jest już sprawdzany pod kątem integralności. Najczęstsza cicha awaria SRI. - Używanie SRI na zasobach same-origin. Atakujący, który może zmodyfikować twój
/wp-includes/js/jquery.js, może też zmodyfikować HTML deklarujący hash. Używaj SRI tylko na zasobach cross-origin. - Obliczanie hasha na złej wersji pliku. Hash musi pasować do dokładnych bajtów, które przeglądarka otrzyma, włącznie z minifikacją lub transformacją po stronie CDN. Zawsze pobieraj z faktycznego URL produkcyjnego przy obliczaniu.
- Nie aktualizowanie hasha przy aktualizacji biblioteki. Aktualizujesz wersję biblioteki w URL, zapominasz zaktualizować
integrity, skrypt cicho przestaje działać. Objawy: funkcjonalność pęka, konsola pokazuje "Failed to find a valid digest in the integrity attribute". - Używanie SHA-1. SHA-1 jest podatne na kolizje i zostało zdeprecjonowane dla SRI. Używaj SHA-384 lub SHA-512.
- Próbowanie używania SRI na CDN bez CORS. Przeglądarka nie może obliczyć hasha, więc SRI jest niemożliwe. Albo CDN musi włączyć CORS, albo musisz samodzielnie hostować plik.
SRI i Content Security Policy (CSP)
SRI i CSP są komplementarne, nie nadmiarowe. CSP mówi "tylko skrypty z tej listy originów mogą działać". SRI mówi "i ten skrypt musi pasować do tego dokładnego hasha". Razem tworzą podejście defense-in-depth: CSP blokuje nieznane originy; SRI blokuje manipulację znanymi originami. CSP z script-src 'self' https://trusted-cdn.com mówi "ufamy trusted-cdn.com"; dodanie hashów SRI do twoich skryptów na trusted-cdn.com zawęża to zaufanie do konkretnych wersji plików.
Robocza dyrektywa CSP require-sri-for script wymuszałaby, aby każdy skrypt cross-origin musiał mieć atrybut integrity, na poziomie przeglądarki. W 2026 roku ma ograniczone wsparcie, ale to kierunek, w którym podąża standard.
Co sprawdza InspectWP
Sekcja Bezpieczeństwa każdego raportu InspectWP sprawdza zewnętrzne tagi skryptów i arkuszy stylów oraz raportuje, które zawierają atrybuty integrity, a które nie. Brakujące SRI w skrypcie z CDN strony trzeciej jest oznaczane jako znalezisko niskiej do średniej dotkliwości, w zależności od kontekstu. Strona logowania lub checkoutu ładująca zewnętrzny JavaScript bez SRI to ostrzeżenie o wyższym priorytecie. Raport oznacza również źle sformułowane wartości integrity (zły prefiks algorytmu, niepoprawne base64), które mogą dać fałszywe poczucie ochrony, podczas gdy są faktycznie ignorowane przez przeglądarkę. SRI to jeden z tych środków, w których istnienie atrybutu liczy się mniej niż jego poprawność; zły hash jest funkcjonalnie równoważny brakowi hasha, ponieważ przeglądarka nadal odrzuca niezgodności, ale brakujący atrybut crossorigin sprawia, że cała kontrola jest cicha.