Podejrzewasz skimmer na kasie?Zamów audyt kasy
← Blog
Bezpieczeństwo

Jak sprawdzić, czy checkout sklepu nie kradnie kart płatniczych

Skimmer na stronie płatności nie spowalnia sklepu i często nie pokazuje się administratorowi. Jak go szukać i jak ograniczyć szkody, zanim ktoś go podrzuci.

Skimmer w sklepie to skrypt na stronie kasy, który kopiuje dane karty (czasem też hasła klientów) i wysyła je atakującemu. Sklep działa normalnie, więc żeby go znaleźć, trzeba obejrzeć realny HTML kasy z produktem w koszyku, z przeglądarki, której sklep nie zna, a potem sprawdzić treść stron kasy w bazie, pliki modułów i listę użytkowników z uprawnieniami admina. Przed powrotem chroni Content Security Policy i monitoring strony płatności, czyli to, czego wymaga PCI DSS 4.0 w punktach 6.4.3 i 11.6.1.

Jak działa skimmer na stronie płatności?

W incydentach, które sprzątaliśmy, widzieliśmy trzy warianty:

  • Fałszywy formularz karty (Magecart, WooCommerce). Na kasie pojawiały się dodatkowe pola karty, a przy logowaniu skrypt przechwytywał hasła klientów.
  • Iframe z pliku w legalnym module (PrestaShop). Podrzucony plik siedział w prawdziwym module sklepu. Ładował go „injector” w pliku wykonywanym przy każdym żądaniu, który podmieniał HTML w buforze wyjścia na kroku dostawy i płatności. Działał ok. 9 miesięcy, a zdalny dostęp przez menedżer plików w module ok. 16 miesięcy.
  • Loader w treści strony kasy w bazie. Fragment udający Google Tag Manager siedział w post_content strony kasy. Adres serwera atakującego czytał z kontraktu na blockchainie (technika EtherHiding), więc w kodzie nie było żadnej podejrzanej domeny.

Dlaczego administrator nie widzi skimmera?

Bo skimmer jest do tego zaprojektowany. W sklepie WooCommerce fałszywy formularz nie pokazywał się adminom, bo skrypt rozpoznawał ich adres IP i ciasteczko, więc każdy test z konta lub sieci administratora pokazywał czystą stronę. Wariant z PrestaShop ustawiał ofierze cookie, żeby nie pokazać się jej drugi raz. Do tego pusta kasa w WooCommerce robi przekierowanie 302 do koszyka, więc kto sprawdza kasę bez produktu w koszyku, ogląda zupełnie inną stronę niż klient, który właśnie płaci.

Narzędzia też dają fałszywe „czysto”:

  • diff rdzenia PrestaShop z oficjalnym wydaniem objął 4269 plików, pokazał 28 zmian i 0 złośliwych, bo wszystkie elementy skimmera leżały w modules/ i vendor, poza zakresem porównania,
  • skan bazy obejmował tylko wp_options i przeoczył loader w treści strony kasy,
  • data modyfikacji podrzuconego pliku była sfałszowana na 2019 rok, więc wyszukiwanie „plików zmienionych ostatnio” go omijało,
  • 7 ukrytych administratorów miało rolę „customer” z uprawnieniami nadanymi bezpośrednio, więc lista adminów w panelu ich nie pokazywała.

Dlatego szybciej znajdziesz skimmer, szukając mechanizmu, czyli odpowiedzi na pytanie, w jaki sposób kod trafia na stronę kasy, niż przeszukując pliki pod kątem sygnatur znanego malware.

Jak sprawdzić checkout sklepu krok po kroku?

  1. Otwórz kasę jak klient. Okno prywatne, inna sieć niż firmowa (np. telefon na LTE), produkt w koszyku. Zapisz źródło strony kasy do pliku.
  2. Przeszukaj HTML pod kątem wskaźników. Trafienie nie jest dowodem, bo legalne biblioteki też używają np. atob, ale każde trzeba wyjaśnić.
grep -oE "JsonRpcProvider|ethers@|crypto\.subtle|atob\(|eval\(|fromCharCode|createElement\(.script.\)|new WebSocket|sendBeacon" kasa.html | sort | uniq -c
grep -oE 'src="https?://[^/"]+' kasa.html | sort -u
  1. Sprawdź domeny i GTM. Każda domena w src musi być Twoja albo Twojego dostawcy. ID kontenera GTM (GTM-...) w kodzie ma być tym samym, które widzisz w swoim koncie Tag Managera.
  2. Zajrzyj do treści stron kasy i koszyka w bazie, nie tylko do wp_options:
wp post get $(wp option get woocommerce_checkout_page_id) --field=post_content | grep -i "<script"
wp post get $(wp option get woocommerce_cart_page_id) --field=post_content | grep -i "<script"
  1. Sprawdź użytkowników po uprawnieniach, nie po roli. To zapytanie pokaże konta bez roli administratora, które mają uprawnienia admina (prefiks tabel może być inny niż wp_):
SELECT user_id, meta_value FROM wp_usermeta
WHERE meta_key = 'wp_capabilities'
  AND meta_value NOT LIKE '%administrator%'
  AND (meta_value LIKE '%manage_options%' OR meta_value LIKE '%edit_plugins%');
  1. Przejrzyj pliki modułów i wtyczek, nie tylko rdzeń. Szukaj kodu, który modyfikuje bufor wyjścia albo dokleja iframe do kasy. Weryfikuj treścią i sumami kontrolnymi, nie datą modyfikacji.

Masz ten sam problem? Sprawdzimy Twoją kasę z produktem w koszyku, treść stron w bazie i pliki modułów. Opisz sytuację →

Jak Content Security Policy blokuje skimmer?

Skimmer działa w przeglądarce klienta, więc blokada IP serwera atakującego nic nie daje: w naszym przypadku stał za Cloudflare i się zmieniał. Działa CSP, czyli nagłówek, który mówi przeglądarce, skąd wolno ładować skrypty (script-src) i dokąd wolno wysyłać dane (connect-src), więc kod, który próbuje wysłać numer karty na serwer spoza tej listy, zostaje zablokowany w przeglądarce klienta.

Wdrażamy to w kolejności:

  1. Najpierw nagłówek Content-Security-Policy-Report-Only, który tylko raportuje naruszenia. W jednym ze sklepów po teście na 7 typach stron było 0 naruszeń.
  2. Potem tryb wymuszający, z wyłączeniem /wp-admin.
  3. Zamiast całego jsdelivr czy unpkg dopuszczamy konkretne ścieżki bibliotek. Cała domena CDN to furtka, bo każdy może tam opublikować własny pakiet.
  4. Test: w konsoli przeglądarki na kasie próba załadowania biblioteki ethers i zapytanie fetch do węzła RPC blockchaina mają skończyć się błędem CSP.
Content-Security-Policy-Report-Only:
  script-src 'self' https://www.googletagmanager.com https://cdn.jsdelivr.net/npm/[email protected]/;
  connect-src 'self' https://www.google-analytics.com;
  report-uri /csp-report

W prawdziwym nagłówku to jedna linia. Każdy nowy tag marketingowy oznacza nowy wpis w CSP, więc zespół marketingu musi o tym wiedzieć, zanim doda kolejny piksel przez GTM, bo inaczej przeglądarka go zablokuje, a raport pokaże naruszenie.

Czy SRI i bramka płatności wystarczą?

SRI (atrybut integrity przy tagu script) sprawdza, czy plik z CDN nie zmienił się od momentu, w którym wpisałeś jego skrót, i blokuje go, jeśli ktoś podmienił zawartość na serwerze dostawcy. Nie chroni jednak przed kodem wstrzykniętym w treść strony ani przed skryptami dynamicznymi, takimi jak GTM. Płatność przez przekierowanie albo iframe bramki zmniejsza ryzyko, ale fałszywy formularz karty da się dołożyć przed przekierowaniem.

Co wymaga PCI DSS 4.0 od strony płatności?

WymaganieTreśćJak to spełniamy w praktyce
6.4.3inwentarz skryptów na stronie płatności, autoryzacja każdego, zapewnienie integralnościlista skryptów z kasy, CSP z konkretnymi ścieżkami, SRI dla plików z CDN
11.6.1wykrywanie nieautoryzowanych zmian nagłówków HTTP i treści strony płatnościmonitoring HTML kasy i plików z alertem

Oba wymagania są obowiązkowe od 31 marca 2025. Zakres zależy od sposobu przyjmowania płatności, więc ustal go z operatorem płatności lub agentem rozliczeniowym.

Jak monitorować kasę, żeby skimmer nie wrócił?

  • Skrypt co 10 minut, który tylko wykrywa. Nie kasuje niczego sam, bo automatyczne kasowanie niszczy ślady potrzebne do ustalenia, którędy wszedł atakujący i od kiedy skimmer działał.
  • Alert przez zewnętrzny SMTP. W jednym sklepie lokalna poczta serwera nie dostarczała wiadomości przez 5 tygodni.
  • Test detektora na próbce. Zły regex plus wyciszone błędy dają fałszywe „czysto”. Podrzuć nieszkodliwy plik ze wskaźnikiem i sprawdź, czy alert przychodzi.

Co zrobić, gdy znajdziesz skimmer?

Najpierw zabezpiecz kopię plików, bazy i logów. Potem usuwaj, pamiętając o OPcache: w jednym przypadku chmod 000 na pliku skimmera nic nie dał, bo PHP trzymał skompilowaną wersję w pamięci, i pomógł dopiero restart PHP-FPM. Jeśli sklep stoi za Cloudflare, a logi nie zapisują nagłówka CF-Connecting-IP, nie ustalisz IP atakującego, więc dodaj go do formatu logów od razu.

Policz skalę. W jednym incydencie przez zainfekowaną kasę przeszły 234 zamówienia od 140 klientów, a 33 klientom wyciekło hasło. Na zgłoszenie do UODO jest 72 godziny od stwierdzenia naruszenia. Pozostałe kroki po włamaniu opisaliśmy w tekście o tym, co robić z wirusem na stronie WordPress.

Jeśli wolisz to zlecić, ASAPDevs robi audyt bezpieczeństwa sklepu i usuwanie malware: od sprawdzenia kasy po wdrożenie CSP i monitoringu.

Źródła

Kamil Perzowski
Kamil Perzowski
CEO i co-founder ASAPDevs. Programuje i utrzymuje sklepy, aplikacje webowe i serwery klientów. LinkedIn · Zamów audyt kasy
Masz ten sam problem?

Podejrzewasz skimmer na kasie?

Kamil Perzowski, ASAPDevs
Kamil Perzowski
CEO & Co-founder, ASAPDevs
Sprawdzamy stronę płatności WooCommerce i PrestaShop, usuwamy skimmery i wdrażamy CSP oraz monitoring zgodny z PCI DSS 4.0. Pilne? Zadzwoń: +48 884 220 764.
★★★★★
Współpracujemy już z 5 lat w różnych aspektach. Sam fakt, że nigdy nie przeszło mi przez myśl współpracować z inna firmą mówi o wszystkim Pełen profesjonalizm, terminowość, kreatywność, inicjatywy...długo by wymieniać. Wszystko się zgadza. Naprawdę polecam.
Michał B., opinia w Google
  1. Czytam zgłoszenie i odpisuję z pytaniami albo propozycją terminu rozmowy.
  2. Krótka rozmowa o zakresie, dostępach i terminie.
  3. Dostajesz plan i wycenę. Decydujesz, bez zobowiązań.

Wolisz od razu porozmawiać? +48 884 220 764 · [email protected]

Wysyłając formularz, przekazujesz nam dane, żebyśmy mogli odpowiedzieć. Szczegóły w polityce prywatności.

FAQ

Pytania i odpowiedzi

Jak sprawdzić, czy sklep internetowy kradnie dane kart?

+
Otwórz kasę jak zwykły klient: w oknie prywatnym, z innej sieci i z produktem w koszyku. Zapisz HTML strony i poszukaj obcych domen w src, innego ID kontenera GTM niż Twoje oraz fragmentów typu JsonRpcProvider, atob( czy sendBeacon. Sprawdź też treść strony kasy w bazie i listę użytkowników z uprawnieniami administratora.

Dlaczego nie widzę skimmera, gdy wchodzę na kasę jako administrator?

+
Bo skimmery często ukrywają się przed adminem: rozpoznają jego adres IP albo ciasteczko i wtedy nie wstrzykują formularza. Część ustawia też cookie ofierze, żeby nie pokazać się jej drugi raz. Testuj z czystej przeglądarki i spoza sieci firmowej.

Czy płatność przez przekierowanie do bramki chroni przed skimmerem?

+
Ogranicza ryzyko, bo dane karty wpisuje się na stronie operatora. Atakujący może jednak dołożyć na Twojej kasie fałszywy formularz karty przed przekierowaniem. Klient wpisze dane karty dwa razy.

Co mówi PCI DSS 4.0 o skryptach na stronie płatności?

+
Wymaganie 6.4.3 każe prowadzić inwentarz skryptów na stronie płatności, autoryzować każdy z nich i zapewnić ich integralność. Wymaganie 11.6.1 wymaga mechanizmu wykrywającego nieautoryzowane zmiany nagłówków HTTP i treści tej strony. Oba są obowiązkowe od 31 marca 2025.

Ile mam czasu na zgłoszenie wycieku danych klientów?

+
Na zgłoszenie naruszenia do UODO masz 72 godziny od jego stwierdzenia. Przygotuj listę zamówień i klientów, którzy przeszli przez zainfekowaną kasę w okresie działania skimmera.

Przeczytaj też