LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Przegląd bloga /Tworzenie stron internetowych/Tutorials / Tutorial: Odczyt zminifikowanego skryptu obcego, zanim trafi...
Ten artykuł w innych językach:

Tutorial: Odczyt zminifikowanego skryptu obcego, zanim trafi na stronę

Tutorial: Odczyt zminifikowanego skryptu obcego, zanim trafi na stronęTutorial: Odczyt zminifikowanego skryptu obcego, zanim trafi na stronę

Management Summary

Zewnętrzne skrypty dodają usługi do witryny, ale mogą też odczytywać informacje strony i łączyć się z innymi serwerami. Kod zminifikowany jest zagęszczony do trudnej do czytania postaci, aby ograniczyć rozmiar pobrania. Artykuł wyjaśnia, jak analiza kodu i zachowania pomaga zrozumieć dostęp wprowadzany przed instalacją. Wspiera to kontrolę udostępniania danych i późniejszych zmian. Sam kod witryny nie ujawnia jednak wszystkiego, co dostawca robi z informacjami po ich otrzymaniu.

Spis treści
  1. Odtwarzalna kopia przed analizą
  2. Sześć przeszukań potencjalnych funkcji
  3. Minifikacja i zaciemnianie
  4. Lista hostów nie tworzy automatycznie polityki CSP
  5. SRI przypina sprawdzone bajty
  6. Pytania i odpowiedzi
  7. Źródła

Skrypt zewnętrzny uruchomiony bezpośrednio na stronie może korzystać z DOM-u i wielu interfejsów przeglądarki z uprawnieniami tej strony. DOM to reprezentacja strony w przeglądarce, obejmująca tekst, formularze i inne elementy. Nadal obowiązują granice przeglądarki: ramki z innych originów, ciasteczka HttpOnly i interfejsy wymagające uprawnień nie stają się automatycznie dostępne. Przegląd musi więc ustalić rzeczywisty kontekst integracji.

Formatowanie i wyszukiwanie słów kluczowych pomagają przy pierwszej kontroli. Sześć przeszukań nie opisuje jednak wszystkich możliwości, nie dowodzi nieszkodliwości i nie zastępuje przeglądu bezpieczeństwa. Przydatny wynik to zapis dowodów: dokładny plik, potencjalne funkcje, zaobserwowane zachowanie, wymagane cele i otwarte pytania.

Odtwarzalna kopia przed analizą

Poniższy przykład Bash wymaga curl, sha256sum oraz już zainstalowanej, zatwierdzonej wersji js-beautify. Zarezerwowany adres przykładowy wymaga zastąpienia rzeczywistym adresem dostawcy. Osobny katalog przeglądu zachowuje każdą kopię z datą. Pobieranie zapisuje nagłówki i końcowy URL, odrzuca błędy HTTP i dopuszcza tylko przekierowania HTTPS. Pobrany skrypt nie jest wykonywany.

Shell
set -eu
curl --fail --show-error --silent --location   \
  --proto '=https' --proto-redir '=https'   \
  --connect-timeout 10 --max-time 60   \
  --dump-header widget.headers.txt   \
  --write-out '%{url_effective}\n'   \
  --output widget.raw.js \
  'https://cdn.vendor.example/widget.js' > widget.final-url.txt
test -s widget.raw.js
sha256sum widget.raw.js > widget.sha256
js-beautify --version
js-beautify widget.raw.js -o widget.pretty.js

Nawet udane pobranie wymaga sprawdzenia treści i Content-Type: strona logowania HTML ze statusem 200 nie jest oczekiwanym JavaScriptem. Wersja narzędzia formatującego i czas pobrania należą do dokumentacji. Podstawą sum kontrolnych pozostają niezmienione bajty; sformatowana kopia służy czytaniu. Różnica rozmiaru nie jest miarą bezpieczeństwa ani wiarygodnym pomiarem kompresji transmisji.

Formatowanie nie odtwarza nazw, komentarzy ani struktury źródeł usuniętych podczas budowania. Mapy źródeł przypisują miejsca w dostarczonym pliku do oryginalnego kodu. Dostępne mapy mogą ułatwić analizę, lecz muszą odpowiadać dostarczonemu plikowi. DevTools pozwala też zapisać treść odpowiedzi i wyeksportować zapis sieciowy, więc kontrola w przeglądarce może być udokumentowana. Zapisane adresy i dane żądań mogą wymagać oczyszczenia przed udostępnieniem.

Sześć przeszukań potencjalnych funkcji

Przykłady wykrywają niektóre częste zapisy. Trafienie może znajdować się w komentarzu albo nieużywanej gałęzi; brak trafienia nie wyklucza danej możliwości. Skrypt może wywołać globalThis["fe" + "tch"](...), użyć aliasu lub wczytać inny plik. Sześć kategorii porządkuje pracę, a nie certyfikuje skrypt.

Shell
# Network-related candidates
grep -nE 'fetch[[:space:]]*\(|XMLHttpRequest|sendBeacon|WebSocket|EventSource|new[[:space:]]+Image' widget.pretty.js
# Storage and cookie candidates
grep -nE 'localStorage|sessionStorage|cookie|indexedDB|caches' widget.pretty.js
# Additional code or resource loading
grep -nE 'createElement|import[[:space:]]*\(|importScripts|Worker|\.src[[:space:]]*=' widget.pretty.js
# Input and form handling
grep -nE 'addEventListener|oninput|onkeydown|onsubmit|FormData|\.value' widget.pretty.js
# Device and rendering features
grep -nE 'getContext|toDataURL|AudioContext|hardwareConcurrency|RTCPeerConnection' widget.pretty.js
# Literal HTTP(S) host candidates only
grep -oiE 'https?://[a-z0-9.-]+' widget.pretty.js | sort -u

Wyszukiwanie pamięci nie odróżnia odczytu od zapisu. Pamięć sesyjna nie oznacza przechowywania bez końca. Obsługa wejścia wymaga sprawdzenia rzeczywistego elementu, delegowania zdarzeń, odczytywanych wartości i późniejszej transmisji. Samo użycie canvas, audio lub WebRTC nie dowodzi fingerprintingu: możliwe są również testy funkcji i prawidłowe renderowanie. O ustaleniu rozstrzygają cel i przepływ danych.

O zgodzie nie rozstrzyga samo połączenie „zapis i transmisja”. Odczyt informacji z urządzenia może mieć znaczenie bez nowego ciasteczka. Skrypt bez trafień słów kluczowych nie jest automatycznie nieszkodliwą pomocą w renderowaniu. Cel, operacje dostępu i zapisu, dane osobowe oraz mające zastosowanie wyjątki wymagają osobnej oceny. Wytyczne EROD opisują zakres techniczny szerszy niż tradycyjne ciasteczka.

Cztery uzupełniające kontrole: zachowane źródło, izolowane testy działania, reguły zasobów CSP i integralność.
Trafienia są tropami do analizy. Żadna pojedyncza kontrola nie określa całego przyszłego zachowania skryptu.

Minifikacja i zaciemnianie

Minifikacja zmniejsza kod, np. przez usuwanie odstępów i skracanie nazw wewnętrznych, a zaciemnianie ma utrudniać jego zrozumienie. Tablice kodowanych ciągów, obliczane nazwy właściwości i dynamiczne generowanie kodu są tropami do analizy, nie dowodem szkodliwego zamiaru. Dekodowanie Base64 przez atob ma prawidłowe zastosowania niezwiązane z obrazami. Z kolei obliczany dostęp do właściwości może ominąć proste wyszukiwanie bez rozbudowanego zaciemniania.

Shell
grep -nE 'eval[[:space:]]*\(|Function[[:space:]]*\(|atob[[:space:]]*\(|String\.fromCharCode|\\x[0-9a-fA-F]{2}' widget.pretty.js

Zaciemniony kod nadal może podlegać analizie przez dekodowanie, mapy źródeł lub specjalistyczną analizę statyczną. Izolowany test działania dostarcza innego rodzaju dowodów, ale wyłącznie dla wykonanych ścieżek. Strona testowa powinna zawierać dane syntetyczne i nie korzystać z aktywnych kont produkcyjnych. Nieznany kod nie powinien trafiać do zwykłej zalogowanej przeglądarki ani na witrynę produkcyjną tylko w celu obserwacji zachowania.

Lista hostów nie tworzy automatycznie polityki CSP

Wyrażenie hostów powyżej celowo znajduje tylko proste, dosłowne prefiksy HTTP(S). Pomija adresy względne, adresy bez podanego protokołu, WebSockety, kodowane ciągi i cele składane dynamicznie; usuwa też informację o porcie. Komentarze i adresy dokumentacji mogą dawać nieistotne trafienia. Content Security Policy (CSP) określa dozwolone źródła skryptów, połączeń i innych zasobów przeglądarki. Użyteczny wykaz celów łączy kontekst kodu, rzeczywiste żądania, przekierowania i dokumentację dostawcy.

Typ zasobu określa dyrektywę CSP: ładowanie skryptu, połączenia API i pobieranie obrazów to różne operacje. Sam host w tekście nie uzasadnia dopuszczenia hosta. Poniższy przykład trybu raportowania przedstawia małą fikcyjną witrynę. Domeny i odbiornik raportów są zastępcze; pełna polityka aplikacji wymaga własnego przeglądu.

Tekst
Reporting-Endpoints: csp="https://reports.site.example/csp"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://cdn.vendor.example; connect-src 'self' https://api.vendor.example; img-src 'self' https://images.vendor.example; report-to csp

Każdy nagłówek zajmuje jedną linię nagłówka HTTP. Punkt odbioru raportów musi rzeczywiście istnieć. Report-Only obserwuje naruszenia bez blokowania. Raporty zależą od obsługi w przeglądarce, dostarczenia i wykonanych ścieżek. Brak zgłoszeń nie dowodzi kompletności, a stały tydzień nie obejmuje wszystkich warunków. Obserwacja konsoli i sieci nadal należy do testu.

Lista dozwolonych hostów nie przypina treści pliku. Kolejny skrypt z już dopuszczonego hosta może załadować się bez nowego wpisu. Przy zaufaniu opartym na nonce lub hashu i 'strict-dynamic' obsługujące mechanizm przeglądarki mogą również dopuszczać dynamicznie ładowane zależności bez osobnych wpisów hostów. CSP nie zamyka więc każdej luki pozostawionej przez niezmieniony skrypt ładujący.

SRI przypina sprawdzone bajty

Dla odpowiedniej stabilnej odpowiedzi skryptu Subresource Integrity porównuje bajty z oczekiwanym hashem przed wykonaniem. Hash musi pochodzić ze sprawdzonego, niezmienionego pliku, a nie ze sformatowanej kopii. Ten przykład Pythona wypisuje rzeczywistą wartość integralności SHA-384:

Python
import base64
import hashlib
from pathlib import Path

raw = Path("widget.raw.js").read_bytes()
digest = base64.b64encode(hashlib.sha384(raw).digest()).decode("ascii")
print("sha384-" + digest)

Pełny wynik zastępuje poniższy tekst zastępczy. Tekst zastępczy celowo nie jest prawidłowym hashem do wdrożenia.

HTML
<script src="https://cdn.vendor.example/widget.js"
        integrity="sha384-REPLACE_WITH_REVIEWED_BASE64_DIGEST"
        crossorigin="anonymous"></script>

Inna odpowiedź nie przechodzi sprawdzenia integralności. Aplikacja potrzebuje określonego zachowania przy takim błędzie; automatyczne przyjęcie aktualnego hasha dostawcy nie byłoby ponownym przeglądem. SRI między różnymi originami wymaga też odpowiedniej odpowiedzi CORS. crossorigin="anonymous" stosuje CORS z trybem poświadczeń same-origin: poświadczenia są pomijane dla innego originu, lecz nadal mogą być wysyłane dla tego samego.

Zmienny kontener tagów nie jest z zasady niezgodny z hashowaniem. W praktyce dynamiczne lub spersonalizowane odpowiedzi, brak obsługi CORS i częste publikacje mogą sprawić, że stabilne wdrożenie SRI jest nieodpowiednie albo nieobsługiwane przez dostawcę. Bez przypięcia potrzebne pozostają kontrola publikacji, sprawdzone wersje i monitoring. Żaden z tych mechanizmów nie zatwierdza dowolnego przyszłego kodu.

Pytania i odpowiedzi

Czy hash skryptu ładującego obejmuje wszystkie zależności?

Nie. Hash elementu script obejmuje zasób pobrany dla tego elementu, a nie wszystkie później ładowane skrypty lub odpowiedzi konfiguracyjne. Dynamicznie tworzony skrypt może otrzymać własne metadane integralności, jeśli skrypt ładujący to obsługuje. W pozostałych przypadkach każda zależność wymaga osobnej oceny; dozwolony host nie gwarantuje integralności.

Czy niezmieniony cotygodniowy hash dowodzi tego samego zachowania?

Nie. Identyczne bajty mogą zachowywać się inaczej przez zdalną konfigurację, czas, lokalizację, zgodę, stan konta lub zmienione zależności. Zmieniony hash jest sygnałem do przeglądu, a nie werdyktem. Częstotliwość porównań powinna odpowiadać procesowi aktualizacji i ryzyku integracji, a testy działania obejmować istotne warunki.

Co obejmuje przegląd aktualizacji?

  1. Nowa niezmieniona kopia wraz z dowodami pobrania, obok poprzednio zaakceptowanej wersji.
  2. Porównanie kodu, potencjalnych celów i zależności w kontekście; zmiana minifikacji może utrudnić porównanie wierszy.
  3. Izolowane testy odpowiednich stron, stanów zgody i interakcji, z obserwacją sieci oraz pamięci.
  4. Udokumentowana decyzja dotycząca każdego nowego celu lub funkcji przed zmianą CSP albo zaakceptowanej wartości integralności.

Wykorzystania danych na serwerze, retencji i dalszego udostępniania nie da się ustalić wyłącznie z kodu przeglądarki. Potrzebne są dowody dostawcy i odpowiednia dokumentacja umowna. Przegląd techniczny precyzuje pytania, ale nie weryfikuje samodzielnie całego łańcucha przetwarzania dostawcy.

Lukas Wójcik

Lukas Wójcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Kontakt

Masz pytanie lub pomysł na projekt internetowy? Napisz krótko, o co chodzi. Formularz korzysta z reCAPTCHA i formconfirmed do ochrony przed spamem.

Napisanie komentarza

Przypadki brzegowe pominięte w artykule i pytania o kod są tu mile widziane.

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.

LUKASWOJCIK.COM · NEWSLETTER

Nowe pomysły w skrzynce

Nowe artykuły, praktyczne narzędzia i informacje o projektach.

Wybierz tematy (opcjonalnie)
Bez wyboru: wszystkie tematy.

Zapis wymaga potwierdzenia e-mailem. · Prywatność

Prywatność · Newsletter

Adres e-mail, język, wybrane tematy oraz daty zapisu i potwierdzenia są przechowywane w celu wysyłki newslettera. Wymagane jest potwierdzenie zapisu. Każda wiadomość zawiera link do natychmiastowej rezygnacji. Formconfirmed chroni formularz przed spamem. Brak śledzenia otwarć i kliknięć.

Pełna polityka prywatności ↗