sysadmin.ecommerce > bb-log-279-log-279-atak-na-checkout-jak-zabezpieczyc-formular.md
root@prod-01:~/blog# cat bb-log-279-log-279-atak-na-checkout-jak-zabezpieczyc-formular.md
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Data: 2025-10-10 | Kategoria: Bezpieczeństwo & Backup | Czas czytania: 9 min
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Atak na checkout: Jak zabezpieczyć formularze płatności w e-commerce przed wstrzykiwaniem skryptów (Magecart)

###02

Wstęp: Dlaczego Twoje WAF nie zatrzyma Magecart?

Większość administratorów platform e-commerce koncentruje swoje wysiłki na obronie przed atakami wolumetrycznymi DDoS, próbami brute-force czy exploitami SQL Injection. Tymczasem najbardziej dewastujące finansowo i wizerunkowo ataki omijają te zabezpieczenia, uderzając bezpośrednio w przeglądarki klientów. Mowa o złośliwym oprogramowaniu z rodziny Magecart, znanym jako cyfrowy skimming (digital skimming).

Gdy napastnik przełamie zabezpieczenia systemu CMS (np. wykorzystując podatną wtyczkę w Magento, WooCommerce czy PrestaShop), nie niszczy bazy danych ani nie defacuje strony. Jego działanie jest znacznie subtelniejsze: wstrzykuje kilka linijek kodu JavaScript do plików obsługujących proces finalizacji zamówienia (checkout). Kod ten w locie przechwytuje numery kart kredytowych, dane logowania, a nawet kody BLIK wpisywane przez klientów i wysyła je na zdalny serwer przestępców – dokładnie tak, jak w głośnych przypadkach British Airways, Newegg czy Ticketmaster. W tym artykule przeprowadzimy zaawansowany hardening: zaimplementujemy ścisłe nagłówki HTTP, mechanizmy Content Security Policy (CSP) z tokenami nonce, Subresource Integrity (SRI) oraz restrykcyjną konfigurację systemu plików, które wspólnie uniemożliwią wykonanie i eksfiltrację złośliwego kodu.

Anatomia zagrożenia: Czym jest cyfrowy skimming?

Złośliwy skrypt JavaScript może trafić na stronę Twojego sklepu dwiema głównymi drogami:

  1. Skompromitowany zasób lokalny: Napastnik uzyskuje dostęp do serwera i modyfikuje legalny plik .js (np. checkout.js lub app.min.js), dodając do niego swój ładunek.
  2. Atak na łańcuch dostaw (Third-Party Scripts): Napastnik przejmuje serwer zewnętrznej usługi, z której korzystasz – np. widgetu czatu na żywo, skryptu analitycznego czy narzędzia do zbierania opinii. W tym scenariuszu Twój serwer pozostaje nienaruszony, ale przeglądarka klienta pobiera zainfekowany skrypt z zaufanego, skompromitowanego źródła.

Gdy tylko złośliwy skrypt uruchomi się w kontekście podstrony /checkout, zyskuje pełen dostęp do modelu DOM (Document Object Model). Może nasłuchiwać zdarzeń input na polach formularza płatności i wysyłać przechwycone dane za pomocą ukrytego żądania fetch() lub XMLHttpRequest na zewnętrzną, kontrolowaną przez atakujących domenę (tzw. bramka eksfiltracji).

Bezpieczne wdrażanie CSP: Tryb Report-Only jako pierwszy krok

Wdrożenie rygorystycznego CSP na działającej platformie w trybie „enforce” niemal zawsze kończy się zablokowaniem krytycznych, legalnych skryptów i zatrzymaniem sprzedaży. Dlatego pierwszym, niezbędnym etapem jest uruchomienie polityki w trybie pasywnym. W tym trybie przeglądarka wykona wszystkie skrypty, ale każdy przypadek naruszenia polityki zostanie wysłany jako raport na wskazany endpoint.

W konfiguracji Nginx dla vhosta definiujemy najpierw tryb diagnostyczny, który pozwoli zebrać dane o fałszywych alarmach bez wpływu na działanie sklepu:

nginx

# Etap 1: Wdrażanie testowe - loguje anomalie, ale niczego nie blokuje
add_header Content-Security-Policy-Report-Only "
    default-src 'self';
    script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://secure.payu.com https://secure.przelewy24.pl https://js.stripe.com;
    report-uri /csp-violation-endpoint;
" always;

Kluczowe jest skonfigurowanie endpointu /csp-violation-endpoint do odbierania i logowania raportów JSON wysyłanych przez przeglądarki. Dopiero po przeanalizowaniu logów i upewnieniu się, że nie blokujemy żadnych legalnych zasobów, można przejść do pełnej blokady w trybie produkcyjnym.

Produkcyjny, restrykcyjny ruleset CSP: Nonce, ścisła polityka i ochrona przed Clickjackingiem

Poniższy nagłówek został zoptymalizowany pod kątem maksymalnego bezpieczeństwa strefy checkoutu przy jednoczesnym zachowaniu pełnej funkcjonalności popularnych bramek płatniczych. Blokuje on wykonywanie nieautoryzowanych skryptów inline za pomocą dynamicznych, kryptograficznych tokenów nonce oraz zabezpiecza przed atakami typu Clickjacking (dyrektywa frame-ancestors).

⚠️ Krytyczne ostrzeżenie: Nigdy nie dodawaj data: do dyrektywy script-src. Jest to bezpieczne wyłącznie dla img-src. Dodanie data: do źródeł skryptów otwiera prostą drogę do całkowitego obejścia CSP, umożliwiając atakującemu wstrzykiwanie skryptów zakodowanych w Base64 bezpośrednio w kodzie HTML.

Dodajemy finalny nagłówek w konfiguracji Nginx dla bloku obsługującego ścieżkę koszyka i finalizacji zamówienia:

nginx

location ~* /(checkout|platnosc|zamowienie|koszyk) {
    
    # Zaawansowane CSP produkcyjne
    add_header Content-Security-Policy "
        default-src 'self';
        script-src 'self' 'nonce-$request_id' 'strict-dynamic' https://www.google.com https://www.gstatic.com https://secure.payu.com https://secure.przelewy24.pl https://js.stripe.com;
        img-src 'self' data: https://secure.payu.com https://secure.przelewy24.pl;
        style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
        font-src 'self' https://fonts.gstatic.com;
        frame-src 'self' https://www.google.com https://secure.payu.com https://secure.przelewy24.pl https://js.stripe.com;
        frame-ancestors 'none';
        connect-src 'self' https://secure.payu.com https://secure.przelewy24.pl https://api.stripe.com;
        object-src 'none';
        base-uri 'self';
        form-action 'self' https://secure.payu.com https://secure.przelewy24.pl;
    " always;

    try_files $uri $uri/ /index.php?$args;
}

Wykorzystanie tokenu nonce w praktyce

Nginx za pomocą zmiennej $request_id generuje unikalny, losowy token dla każdego żądania HTTP. Aby dynamiczny kod JavaScript generowany po stronie backendu (np. konfiguracja bramki płatniczej) został wykonany, musisz przekazać ten sam token do atrybutu nonce w tagu <script> w szablonie aplikacji:

html

<script nonce="TUTAJ_DYNAMICZNIE_WSTRZYKNIETY_NONCE_Z_NGINX">
    const payuConfig = { ... };
</script>

Dyrektywa 'strict-dynamic' w połączeniu z nonce dodatkowo upraszcza politykę, ufając skryptom załadowanym przez już autoryzowany skrypt, co jest bezpieczniejsze niż ręczne dopisywanie długiej listy zaufanych domen.

Integralność zasobów zewnętrznych: Wdrażanie Subresource Integrity (SRI)

Jeśli Twój sklep ładuje biblioteki (np. jQuery, Bootstrap, czcionki) z zewnętrznych serwerów CDN, jesteś podatny na atak typu supply-chain na infrastrukturę tego dostawcy. Aby temu zapobiec, każdy zewnętrzny zasób musi posiadać atrybut integrity (Subresource Integrity) zawierający kryptograficzny hash SHA-384 lub SHA-512 jego zawartości. Jeśli plik na CDN zostanie zmodyfikowany o choćby jeden bajt, przeglądarka odrzuci go i nie wykona.

html

<script src="https://cdn.example.com/js/jquery-3.7.1.min.js" 
        integrity="sha384-1H217gwSVyLSIfaLxTyEAZIaGdOgv8i9S7K6N189ZEF1SGN5dB4N11X1G7N1l111" 
        crossorigin="anonymous"></script>

Hardening systemu plików w Debianie/Ubuntu: Zasada najmniejszych uprawnień

Aby uniemożliwić napastnikowi podmianę lokalnych skryptów .js lub wstrzyknięcie kodu do rdzenia aplikacji, stosujemy zasadę najmniejszych uprawnień (principle of least privilege) w systemie plików. Częstym, krytycznym błędem jest rekurencyjne nadawanie właściciela i uprawnień chown -R www-data:www-data na cały katalog sklepu. W takiej konfiguracji proces PHP-FPM ma prawo modyfikować własne pliki źródłowe, co jest najkrótszą drogą do katastrofy.

Prawidłowa struktura uprawnień:
Pliki źródłowe muszą należeć do dedykowanego użytkownika systemowego (np. deploy), a proces www-data (PHP-FPM/Nginx) powinien mieć do nich dostęp wyłącznie do odczytu. Prawo do zapisu nadajemy tylko dla wyselekcjonowanych katalogów na dane tymczasowe i media.

bash

# Wykonujemy w katalogu głównym sklepu (np. /var/www/sklep)
sudo chown -R deploy:www-data .

# Wszystkie katalogi na 750 (odczyt i wykonanie dla grupy www-data)
find . -type d -exec chmod 750 {} \;

# Wszystkie pliki na 640 (odczyt dla www-data, całkowity brak prawa zapisu dla grupy)
find . -type f -exec chmod 640 {} \;

# OTWIERAMY ZAPIS TYLKO DLA KATALOGÓW NIEPOWIĄZANYCH Z KODEM (dostosuj do swojego CMS)
cd /var/www/sklep
chmod -R 770 var/cache var/logs media/ wp-content/uploads

Wykrywanie anomalii: Monitorowanie integralności plików za pomocą AIDE

Skoro pliki produkcyjne nie powinny się zmieniać poza oknami deploymentowymi, wdrożymy system wykrywania włamań na poziomie hosta (HIDS). Narzędzie AIDE (Advanced Intrusion Detection Environment) utworzy kryptograficzną bazę wzorców wszystkich monitorowanych plików i powiadomi administratora o jakiejkolwiek nieautoryzowanej modyfikacji kodu na dysku.

bash

# Instalacja AIDE
sudo apt update && sudo apt install aide -y

Następnie edytujemy plik konfiguracyjny /etc/aide/aide.conf, definiując regułę monitorującą pliki źródłowe naszej aplikacji, biorąc pod uwagę ich sumy kontrolne SHA-256, uprawnienia, właściciela i rozmiar:

plaintext

# Definicja reguły ContentHider: sprawdza sumę SHA-256, uprawnienia, właściciela, grupę i rozmiar
ContentHider = sha256+permissions+owner+group+size

# Monitorowanie katalogu sklepu
/var/www/sklep/.*\.js$ ContentHider
/var/www/sklep/.*\.php$ ContentHider

Inicjalizujemy bazę danych wzorców:

bash

sudo aideinit

Skrypt automatycznie doda zadanie do crona (/etc/cron.daily/aide). Jeśli jakikolwiek monitorowany plik zostanie zmodyfikowany bez Twojej wiedzy, system natychmiast wyśle raport e-mailem do administratora, umożliwiając szybką reakcję na incydent.

Praktyczna ściągawka audytora: komendy i skanowanie zależności

Poniższy zestaw narzędzi pozwala na szybki audyt konfiguracji nagłówków, uprawnień systemowych oraz weryfikację podatności w zewnętrznych bibliotekach (wektor ataku na łańcuch dostaw).

PolecenieCel użycia
curl -I -X GET https://prod-sklep.pl/checkoutSzybka weryfikacja poprawności zwracania nagłówka Content-Security-Policy.
find /var/www/sklep -type f \( -perm /o+w -o -perm /g+w \)Wyszukiwanie plików, które mają niebezpieczne, globalne uprawnienia do zapisu.
sudo aide --checkRęczne, natychmiastowe uruchomienie skanowania integralności plików.
npm audit lub composer outdatedSkanowanie zależności projektu w poszukiwaniu znanych podatności i przestarzałych pakietów.

Podsumowanie: Kompleksowa ochrona zgodna z PCI-DSS

Kompleksowy hardening strefy checkoutu to już nie opcja, a absolutna konieczność w dobie niezwykle skutecznych ataków typu Magecart. Opisane techniki – odcięcie możliwości wykonywania nieautoryzowanych skryptów inline za pomocą dynamicznych tokenów nonce, zablokowanie ruchu wychodzącego do nieautoryzowanych domen przez ścisłą dyrektywę connect-src CSP oraz wymuszenie integralności plików z CDN przez SRI – tworzą barierę niemożliwą do przebicia dla cyfrowych skimmerów. Połączenie tej warstwy aplikacyjnej z restrykcyjnymi uprawnieniami systemu plików i ciągłym monitorowaniem integralności (AIDE) daje pełną pewność, że dane transakcyjne klientów są bezpieczne, a cała infrastruktura spełnia rygorystyczne wymogi normy PCI-DSS w zakresie zabezpieczeń przed złośliwym kodem.

← Powrot do wszystkich artykulow

// alert_systemowy

Widzisz podobne symptomy na swoim serwerze e-commerce? Nie czekaj na awarię w szczycie ruchu.

→ Przejdź do formularza i zgłoś serwer do audytu zerowego