Zapisano do newslettera!

Adres został dodany do naszej listy mailingowej. Będziesz otrzymywać najnowsze artykuły i aktualizacje prosto na swoją skrzynkę.

Wiadomość wysłana!

Dziękujemy. Otrzymaliśmy Twoją wiadomość i odpowiemy w ciągu 24 godzin.

Aplikacja wysłana!

Dziękujemy. Twoja aplikacja na stanowisko została przyjęta. Nasz zespół ją przejrzy i wkrótce się odezwie.

Security

Jak chronić strony internetowe oparte na PHP przed atakami hakerów: 10 zasad

a computer screen with a bunch of text on it

Aby chronić strony internetowe oparte na PHP przed atakami hakerów, potrzebne są trzy współpracujące ze sobą warstwy zabezpieczeń. Pierwszą jest aktualne i prawidłowo skonfigurowane środowisko uruchomieniowe PHP. Drugą – kod aplikacji, który traktuje każde dane wejściowe jako potencjalne zagrożenie. Trzecią jest monitoring, który pozwala wykryć problem w ciągu kilku minut, a nie miesięcy.

Większość włamań na strony internetowe oparte na PHP nie wykorzystuje skomplikowanych luk typu zero-day. Atakujący najczęściej wykorzystują nieaktualne wersje PHP, niezabezpieczone wtyczki, niebezpieczne mechanizmy przesyłania plików oraz zapytania SQL tworzone przez niebezpieczne łączenie ciągów znaków.

Rosnące zainteresowanie podatnością określaną mianem PHP2SHELL przypomina, jak szybko pojedyncza luka w zabezpieczeniach może zamienić stronę internetową w serwer kontrolowany przez cyberprzestępcę.

W tym poradniku wyjaśniamy, na czym polega ten rodzaj ataku, jakie zagrożenia stwarza dla Twojej firmy oraz w jaki sposób cyberprzestępcy uzyskują dostęp do aplikacji PHP. Przedstawiamy również 10 zasad bezpieczeństwa, które nasz zespół stosuje w każdym realizowanym lub audytowanym projekcie PHP.

Czego uczy nas PHP2SHELL w kontekście zdalnego wykonywania kodu (RCE)?

PHP2SHELL to nazwa, pod którą w ostatnim czasie omawiano w internecie problem związany z bezpieczeństwem PHP. Niezależnie od szczegółów technicznych konkretnego komunikatu o podatności, sama nazwa odnosi się do jednego z najpoważniejszych scenariuszy w bezpieczeństwie aplikacji internetowych: sytuacji, w której zwykłe żądanie HTTP może doprowadzić do uzyskania przez atakującego dostępu do powłoki systemowej (shell) na serwerze.

Cyberprzestępca, który uzyska dostęp do powłoki systemowej, może wykonać na serwerze niemal dowolne działania, między innymi:

  • Odczytać dane dostępowe do bazy danych i wykraść informacje o klientach.
  • Umieścić na serwerze złośliwe oprogramowanie lub skrypty przechwytujące dane kart płatniczych.
  • Wykorzystywać serwer do rozsyłania spamu.
  • Użyć infrastruktury Twojej firmy do przeprowadzania ataków na inne systemy.

Zanim podejmiesz działania na podstawie doniesień medialnych, zweryfikuj informacje w oficjalnych źródłach. Sprawdź rejestr zmian PHP 8, komunikaty bezpieczeństwa dotyczące używanego frameworka lub systemu CMS oraz wpis CVE w bazie National Vulnerability Database.

Ustal, których wersji i konfiguracji dotyczy podatność, a następnie zainstaluj odpowiednie aktualizacje. Nazwy podatności i wpisy na blogach rozprzestrzeniają się szybciej niż rzetelne informacje techniczne, dlatego najważniejsze jest działanie na podstawie potwierdzonych danych.

Potwierdzony przykład: CVE-2024-4577

Dobrze udokumentowanym przykładem ataku prowadzącego od żądania HTTP do uzyskania dostępu do powłoki systemowej jest podatność CVE-2024-4577.

Dotyczyła ona PHP działającego w trybie CGI w systemie Windows z określonymi ustawieniami regionalnymi.

System Windows wykorzystuje mechanizm konwersji znaków określany jako Best-Fit Mapping. W jego wyniku niektóre znaki mogą zostać zamienione na inne. Atakujący mógł wykorzystać tę właściwość, wysyłając znak interpretowany przez PHP jako myślnik. Pozwalało to wstrzyknąć dodatkowe opcje wiersza poleceń do pliku wykonywalnego PHP i doprowadzić do wykonania dowolnego kodu.

Podatność umożliwiała obejście zabezpieczenia wprowadzonego wcześniej w celu naprawienia błędu CVE-2012-1823.

Problem został naprawiony w następujących wersjach PHP:

  • PHP 8.1.29
  • PHP 8.2.20
  • PHP 8.3.8

Podatne były również domyślne konfiguracje XAMPP w systemie Windows. Ataki wykorzystujące tę lukę zostały zaobserwowane w praktyce niedługo po jej ujawnieniu.

Wnioski dla każdego zespołu PHP

- Szybkość instalowania aktualizacji ma kluczowe znaczenie. Od momentu ujawnienia podatności do rozpoczęcia masowych ataków mogą minąć zaledwie dni, a czasami nawet godziny.

- Konfiguracja jest częścią powierzchni ataku. Uruchamianie PHP w trybie CGI zamiast PHP-FPM lub wykorzystywanie środowiska deweloperskiego, takiego jak XAMPP, na serwerze produkcyjnym może zmienić pozornie niszowy problem w krytyczne zagrożenie.

- Wielowarstwowa ochrona ogranicza skutki ataku. Nawet jeśli cyberprzestępcy uda się wykorzystać podatność, potencjalne szkody będą znacznie mniejsze, jeśli proces PHP działa z ograniczonymi uprawnieniami, nie ma możliwości zapisywania plików w katalogu z kodem aplikacji, a ruch wychodzący z serwera jest odpowiednio ograniczony.

- Najpierw należy zinwentaryzować infrastrukturę. Nie można aktualizować serwerów, o których istnieniu się zapomniało. Dotyczy to między innymi starych stron docelowych (landing pages), kopii środowisk testowych i porzuconych paneli administracyjnych.

Jak hakerzy naprawdę włamują się na strony internetowe oparte na PHP?

Cyberprzestępcy rzadko atakują konkretne osoby lub firmy. Zazwyczaj skanują cały internet w poszukiwaniu znanych luk w zabezpieczeniach, a następnie wykorzystują te, które uda im się znaleźć.

Standardowym punktem odniesienia w tej dziedzinie jest zestawienie OWASP Top 10. W projektach PHP regularnie spotykamy te same słabe punkty, które umożliwiają przeprowadzenie ataku:

- Nieaktualne wersje PHP. Korzystanie z wersji, które nie otrzymują już poprawek bezpieczeństwa, stanowi poważne zagrożenie. Sprawdź oficjalną listę wspieranych wersji PHP. Według stanu na 2026 rok PHP 8.1 i starsze wersje zakończyły już cykl wsparcia (End of Life).

- Podatne wtyczki i zależności. Wtyczki WordPressa, przestarzałe pakiety Composer oraz zewnętrzne biblioteki skopiowane do projektu, których nikt regularnie nie aktualizuje.

- Ataki typu SQL Injection. Zapytania do bazy danych budowane bezpośrednio na podstawie parametrów otrzymanych od użytkownika. To wciąż częsty problem w starszym kodzie aplikacji.

- Cross-Site Scripting (XSS). Wyświetlanie danych użytkownika bez odpowiedniego filtrowania i kodowania. Może to prowadzić między innymi do kradzieży sesji użytkowników oraz wstrzykiwania skryptów przechwytujących dane płatnicze.

- Nieograniczone przesyłanie plików. Klasycznym przykładem jest formularz przesyłania zdjęcia profilowego, który akceptuje również pliki z rozszerzeniem .php. W ten sposób atakujący może umieścić na serwerze tzw. web shell, czyli skrypt zapewniający zdalny dostęp do wykonywania poleceń.

- Niebezpieczna deserializacja i dołączanie plików. Wywoływanie funkcji unserialize() na danych dostarczonych przez użytkownika lub używanie include() ze ścieżką utworzoną na podstawie parametru z żądania HTTP.

- Ataki na dane logowania. Ataki siłowe (brute force) oraz credential stuffing, czyli wykorzystywanie wykradzionych wcześniej haseł, wymierzone w panele administracyjne pozbawione ograniczeń liczby prób logowania lub uwierzytelniania wieloskładnikowego (MFA).

- Ujawnione dane poufne. Publicznie dostępne pliki .env, katalogi .git, archiwa kopii zapasowych oraz strony phpinfo(), które mogą ujawniać informacje o konfiguracji serwera.

Żadna z tych metod ataku nie jest nowa – i to dobra wiadomość. Większości opisanych zagrożeń można uniknąć dzięki konsekwentnemu stosowaniu dobrych praktyk programistycznych i odpowiedniej organizacji pracy zespołu. Właśnie na tym koncentrują się przedstawione poniżej zasady bezpieczeństwa.

10 zasad ochrony stron internetowych PHP przed atakami hakerów

Pierwszych pięć zasad dotyczy kodu aplikacji i jej zależności. Kolejne pięć koncentruje się na sesjach, serwerach i codziennym utrzymaniu infrastruktury. Stosowane łącznie pozwalają wyeliminować zdecydowaną większość najczęściej wykorzystywanych luk bezpieczeństwa.

1. Korzystaj z aktualnej, wspieranej wersji PHP i wszystkich zależności

Używaj wersji PHP, która nadal otrzymuje poprawki bezpieczeństwa, i regularnie instaluj aktualizacje kolejnych wydań.

Uruchom polecenie composer audit w procesie CI/CD, aby wykryte podatne pakiety powodowały niepowodzenie procesu budowania aplikacji.

W przypadku stron opartych na systemach CMS włącz automatyczne aktualizacje zabezpieczeń zarówno dla głównego oprogramowania, jak i wtyczek. Usuń również wszystkie nieużywane rozszerzenia – nieaktywna wtyczka nadal może zawierać kod podatny na ataki.

2. Waliduj dane wejściowe i odpowiednio zabezpieczaj dane wyjściowe

Każde dane otrzymywane od użytkownika powinny być sprawdzane pod kątem dozwolonego typu, długości i formatu. Dotyczy to między innymi treści żądań HTTP, parametrów URL, nagłówków, plików cookie oraz danych przesyłanych przez webhooki.

Następnie należy odpowiednio kodować dane wyjściowe, uwzględniając kontekst, w którym są wykorzystywane:

  • HTML: stosuj htmlspecialchars() lub automatyczne kodowanie danych oferowane przez silnik szablonów.
  • JavaScript, adresy URL i atrybuty HTML: każdy z tych kontekstów wymaga odpowiedniego, dedykowanego sposobu kodowania.

Nigdy nie wyłączaj automatycznego kodowania danych (auto-escaping) w Twig lub Blade, chyba że masz pełną kontrolę nad wyświetlaną zawartością.

3. Stosuj przygotowane zapytania (Prepared Statements) do każdej operacji na bazie danych

Zapytania parametryzowane realizowane za pomocą PDO lub ORM eliminują ryzyko SQL Injection, pod warunkiem ich konsekwentnego stosowania.

Szczególną uwagę zwróć na wyjątki, takie jak dynamiczne kolumny ORDER BY, nazwy tabel oraz funkcje umożliwiające wykonywanie surowych zapytań SQL.

W takich przypadkach zamiast bezpośrednio przekazywać dane użytkownika zastosuj listę dozwolonych wartości (allow-list).

4. Zabezpiecz mechanizm przesyłania plików

Przesyłanie plików to jedna z najkrótszych dróg prowadzących od zwykłego żądania HTTP do umieszczenia na serwerze złośliwego skryptu typu web shell. Cztery podstawowe zasady pozwalają znacząco ograniczyć to ryzyko:

  • Sprawdzaj rzeczywisty typ MIME pliku za pomocą funkcji finfo, a nie tylko jego rozszerzenie lub typ zadeklarowany przez przeglądarkę.
  • Generuj losowe nazwy plików zamiast zachowywać nazwy przesłane przez użytkownika.
  • Przechowuj pliki poza katalogiem głównym serwera WWW (web root) lub korzystaj z pamięci obiektowej, takiej jak Amazon S3.
  • Skonfiguruj serwer WWW tak, aby nigdy nie wykonywał kodu PHP znajdującego się w katalogach przeznaczonych na przesyłane pliki.

5. Nie używaj niebezpiecznych funkcji na niezaufanych danych

Funkcje eval(), dynamiczne dołączanie plików za pomocą include i require, wywoływanie unserialize() na danych użytkownika oraz funkcje systemowe, takie jak exec() i system(), mogą prowadzić do zdalnego wykonywania kodu (RCE).

Zamiast unserialize() stosuj json_decode(), jeśli pracujesz z danymi pochodzącymi od użytkownika.

Jeśli aplikacja musi uruchamiać zewnętrzne programy, korzystaj ze sprawdzonych komponentów do zarządzania procesami. Przekazuj argumenty w postaci tablicy, zamiast budować polecenia przez łączenie ciągów znaków.

Poniższy fragment kodu przedstawia kilka z opisanych zasad w praktyce, wykorzystując czysty PHP.

secure-basics.php
<?php
declare(strict_types=1);

// Rule 3: prepared statements, real (not emulated) prepares
$pdo = new PDO($dsn, $dbUser, $dbPass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE email = :email');
$stmt->execute(['email' => $_POST['email'] ?? '']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// Rule 2: escape output for the HTML context
echo htmlspecialchars($user['name'] ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

// Rule 6: never roll your own password hashing
$hash = password_hash($plainPassword, PASSWORD_DEFAULT); // or PASSWORD_ARGON2ID if available
if (password_verify($inputPassword, $hash)) {
    session_regenerate_id(true); // prevent session fixation
}

// Rule 4: verify real file type, random name, store outside web root
$finfo   = new finfo(FILEINFO_MIME_TYPE);
$mime    = $finfo->file($_FILES['avatar']['tmp_name']);
$allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
if (!isset($allowed[$mime])) {
    throw new RuntimeException('Invalid file type');
}
$fileName = bin2hex(random_bytes(16)) . '.' . $allowed[$mime];
move_uploaded_file($_FILES['avatar']['tmp_name'], '/var/app-storage/uploads/' . $fileName);

Zasady 6–10: bezpieczeństwo sesji, zabezpieczenie serwera i monitoring

6. Zadbaj o bezpieczne uwierzytelnianie i zarządzanie sesjami

Stosuj funkcje password_hash() i password_verify() do bezpiecznego przechowywania oraz weryfikowania haseł. Jeśli konfiguracja PHP na to pozwala, wybierz algorytm Argon2id.

Po zalogowaniu użytkownika generuj nowy identyfikator sesji, aby zapobiec atakom typu Session Fixation. Ustaw również odpowiednie parametry plików cookie:

  • HttpOnly – uniemożliwia dostęp do plików cookie z poziomu JavaScript.
  • Secure – zapewnia przesyłanie plików cookie wyłącznie przez połączenia HTTPS.
  • SameSite – ogranicza ryzyko ataków CSRF.

Zabezpiecz panele administracyjne uwierzytelnianiem wieloskładnikowym (MFA). Wprowadź również ograniczenia liczby prób logowania, resetowania haseł i wywołań endpointów API (rate limiting).

Dzięki tym rozwiązaniom można powstrzymać większość ataków wykorzystujących skradzione dane logowania, zanim zagrożą one bezpieczeństwu bazy danych.

7. Wprowadź ochronę CSRF i odpowiednie nagłówki bezpieczeństwa

Każdy formularz i endpoint umożliwiający zmianę danych powinien być zabezpieczony tokenem CSRF. Frameworki Laravel i Symfony oferują takie mechanizmy w standardzie.

Skonfiguruj również następujące nagłówki bezpieczeństwa HTTP:

  • Content-Security-Policy (CSP) – ogranicza skutki ataków XSS.
  • Strict-Transport-Security (HSTS) – wymusza korzystanie z połączeń HTTPS.
  • X-Content-Type-Options: nosniff – zapobiega nieprawidłowemu interpretowaniu typu zawartości przez przeglądarkę.
  • frame-ancestors (w ramach CSP) – chroni przed atakami typu Clickjacking.

Wprowadzenie restrykcyjnej polityki CSP może wymagać dodatkowej pracy, szczególnie w przypadku starszych aplikacji frontendowych. Dlatego warto rozpocząć od trybu raportowania (Report-Only), a następnie stopniowo zaostrzać reguły w kolejnych iteracjach.

8. Zabezpiecz serwer i konfigurację PHP

Uruchamiaj PHP za pomocą PHP-FPM, korzystając z serwera Nginx lub Apache. Unikaj trybu CGI i nigdy nie wykorzystuj środowisk przeznaczonych do programowania, takich jak XAMPP, na serwerach produkcyjnych.

Każda aplikacja powinna działać na osobnym koncie systemowym, posiadającym wyłącznie niezbędne uprawnienia (zasada najmniejszych uprawnień).

Katalog zawierający kod aplikacji powinien być dostępny dla procesu PHP wyłącznie do odczytu. Prawo zapisu należy przyznać tylko konkretnym katalogom przeznaczonym do przechowywania danych, plików tymczasowych i logów.

Ukryj informacje o wersji PHP, wyłącz wyświetlanie błędów użytkownikom i ogranicz dostępność niebezpiecznych funkcji w pliku php.ini, zgodnie z przedstawionym poniżej przykładem.

9. Chroń dane poufne i stosuj zasadę najmniejszych uprawnień

Przechowuj pliki .env i dane uwierzytelniające poza katalogiem głównym serwera WWW (web root). Nigdy nie umieszczaj ich w repozytorium Git.

Zablokuj na poziomie konfiguracji serwera WWW dostęp do katalogów i plików takich jak:

  • .git – zawierających historię i dane repozytorium.
  • Archiwa kopii zapasowych.
  • Pliki konfiguracyjne.
  • Inne pliki zawierające dane poufne.

Użytkownik bazy danych wykorzystywany przez aplikację nie powinien posiadać uprawnień DROP ani GRANT.

Stosuj oddzielne dane dostępowe dla każdego środowiska (produkcyjnego, testowego i deweloperskiego). Zmieniaj hasła i klucze dostępu po każdej zmianie w zespole lub podejrzeniu incydentu bezpieczeństwa.

10. Monitoruj, testuj i przygotuj się na odzyskiwanie danych

Centralizuj logi systemowe i aplikacyjne. Skonfiguruj alerty informujące o:

  • Nagłym wzroście liczby błędów HTTP 4xx i 5xx.
  • Tworzeniu nowych kont administratorów.
  • Nieoczekiwanych zmianach plików w katalogu z kodem aplikacji.

Zapora aplikacyjna WAF lub odpowiednio skonfigurowany reverse proxy mogą zapewnić tymczasową ochronę (tzw. virtual patching) na czas wdrażania właściwych poprawek bezpieczeństwa.

Włącz analizę statyczną kodu, np. za pomocą narzędzi PHPStan lub Psalm z regułami bezpieczeństwa, w procesie CI/CD.

Przeprowadzaj profesjonalne testy penetracyjne (penetration testing) co najmniej raz w roku oraz po każdej większej aktualizacji aplikacji. Nasz zespół zajmujący się testowaniem oprogramowania uwzględnia takie kontrole bezpośrednio w procesie dostarczania oprogramowania.

Nie zapominaj również o automatycznych kopiach zapasowych przechowywanych offline. Regularnie sprawdzaj, czy możliwe jest ich prawidłowe odtworzenie – sama obecność backupu nie gwarantuje możliwości odzyskania danych po ataku.

php.ini (production hardening)
; Hide PHP version and never show errors to visitors
expose_php = Off
display_errors = Off
log_errors = On

; Block remote file inclusion
allow_url_include = Off
; allow_url_fopen = Off  ; only if your app does not fetch remote URLs this way

; Restrict filesystem access to the app and temp dirs
open_basedir = /var/www/app:/var/app-storage:/tmp

; Disable shell functions (check queue workers and tools first)
disable_functions = exec,passthru,shell_exec,system,popen

; Secure sessions
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Lax

; Limit upload size to what the app needs
upload_max_filesize = 5M
post_max_size = 8M

Laravel, Symfony i WordPress – bezpieczeństwo dostosowane do konkretnej technologii

Nowoczesne frameworki zapewniają wiele mechanizmów bezpieczeństwa już w standardzie. Warunkiem jest jednak prawidłowe korzystanie z tych funkcji i unikanie rozwiązań, które omijają wbudowane zabezpieczenia.

Większość problemów wykrywanych podczas audytów bezpieczeństwa wynika z uproszczeń wprowadzanych pod presją czasu i terminów realizacji projektów.

Laravel

Eloquent ORM i Query Builder wykorzystują parametryzację zapytań, co pomaga chronić aplikację przed SQL Injection. Należy jednak zachować szczególną ostrożność przy korzystaniu z metod whereRaw(), DB::raw() i orderByRaw(), jeśli przekazywane są do nich dane pochodzące z żądań użytkownika.

Stosuj właściwości $fillable lub wcześniej zwalidowane dane, aby zapobiegać atakom typu Mass Assignment, polegającym na nieautoryzowanej modyfikacji pól modelu.

W środowisku produkcyjnym zawsze ustaw:

APP_DEBUG=false

Włączony tryb debugowania może ujawniać poufne informacje, w tym zmienne środowiskowe i szczegóły konfiguracji aplikacji.

Zadbaj również o to, aby narzędzia Ignition i Telescope nie były publicznie dostępne.

Nasi programiści PHP i Laravel traktują wszystkie te elementy jako obowiązkowe kryteria bezpieczeństwa przed wydaniem aplikacji.

Symfony

Korzystaj z komponentu Security oraz mechanizmu Voters zamiast tworzyć własne, rozproszone mechanizmy kontroli dostępu w poszczególnych kontrolerach.

W środowisku produkcyjnym wyłącz profiler i pasek debugowania (Debug Toolbar).

Dane poufne przechowuj w bezpiecznym magazynie Symfony Secrets Vault, zamiast umieszczać je w plikach konfiguracyjnych dodawanych do repozytorium Git.

WordPress i inne systemy CMS oparte na PHP

Główne oprogramowanie WordPress jest zazwyczaj dobrze utrzymywane i regularnie aktualizowane. Znacznie większe ryzyko często stanowią dodatkowe wtyczki i motywy.

Aby ograniczyć zagrożenia:

  • Ogranicz liczbę wtyczek i wybieraj wyłącznie te, które są aktywnie rozwijane i regularnie aktualizowane.
  • Wyłącz edytor plików w panelu administracyjnym, korzystając ze stałej DISALLOW_FILE_EDIT.
  • Ogranicz lub wyłącz XML-RPC, jeśli Twoja strona nie korzysta z tej funkcjonalności.
  • Zabezpiecz panel administracyjny uwierzytelnianiem wieloskładnikowym (MFA).

Starsze aplikacje PHP bez frameworka

Starsze aplikacje napisane we własnym PHP, szczególnie te powstałe przed wersją PHP 7, często nie posiadają centralnego mechanizmu walidacji danych wejściowych, przygotowanych zapytań SQL ani tokenów CSRF.

Usuwanie podatności pojedynczy endpoint po drugim jest możliwe, ale czasochłonne i kosztowne.

W dłuższej perspektywie bardziej opłacalnym rozwiązaniem może być stopniowa modernizacja, aktualizacja lub przepisanie aplikacji na nowoczesną technologię.

Nasze podejście do modernizacji starszych systemów (Legacy System Modernization) pozwala realizować takie zmiany etapami, bez konieczności zatrzymywania bieżącej działalności firmy.

A PHP site is rarely hacked because PHP is insecure. It is hacked because someone stopped maintaining it.

Co zrobić, jeśli Twoja strona internetowa oparta na PHP została zhakowana?

W przypadku włamania kluczowe znaczenie mają szybkość działania i zachowanie odpowiedniej kolejności czynności. Zbyt wczesne wyczyszczenie serwera może doprowadzić do utraty dowodów niezbędnych do ustalenia, w jaki sposób cyberprzestępca uzyskał dostęp do systemu. Jeśli pominiesz ten etap, istnieje duże ryzyko, że atak zostanie powtórzony tą samą metodą.

1. Ogranicz skutki ataku. Włącz tryb konserwacji strony lub zastosuj odpowiednią regułę zapory sieciowej, aby ograniczyć dostęp do aplikacji. Zachowaj jednak stan serwera lub wykonaj migawkę dysku (snapshot), zanim rozpoczniesz dalsze działania.

2. Zmień wszystkie dane dostępowe i klucze. Zaktualizuj hasła do bazy danych, klucze API, dane logowania SMTP oraz hasła administratorów. Unieważnij również wszystkie aktywne sesje użytkowników.

3. Znajdź źródło włamania. Przeanalizuj logi serwera WWW i aplikacji, sprawdź ostatnio zmodyfikowane pliki, nieznane skrypty PHP w katalogach przesyłania plików i pamięci podręcznej oraz nowe konta administratorów.

4. Odtwórz aplikację z czystego źródła. Wdróż aplikację z repozytorium Git na nowym, bezpiecznym serwerze, zamiast próbować ręcznie oczyszczać zainfekowany system. Przywróć dane z kopii zapasowej wykonanej przed włamaniem.

5. Usuń przyczynę ataku i wzmocnij zabezpieczenia. Napraw lukę, która umożliwiła włamanie, zaktualizuj oprogramowanie i zastosuj opisane wcześniej zasady bezpieczeństwa, zanim ponownie udostępnisz stronę użytkownikom.

6. Dopełnij obowiązków prawnych. Jeśli doszło do naruszenia ochrony danych osobowych, RODO zasadniczo wymaga zgłoszenia incydentu do właściwego organu nadzorczego w ciągu 72 godzin od momentu stwierdzenia naruszenia. W Polsce organem tym jest Urząd Ochrony Danych Osobowych (UODO). W określonych przypadkach konieczne może być również poinformowanie osób, których dane zostały naruszone.

Jak Midapt zabezpiecza aplikacje PHP – proces, harmonogram i koszty

Najmniej kosztuje bezpieczeństwo, które jest integralną częścią procesu tworzenia oprogramowania, a nie jednorazowym działaniem naprawczym po wystąpieniu problemu.

W każdym projekcie PHP łączymy standardy bezpiecznego programowania ze zautomatyzowanymi kontrolami w procesie CI, obejmującymi analizę statyczną kodu, audyty zależności i testy bezpieczeństwa.

Stosujemy również podejście Infrastructure as Code (IaC), wykorzystując odpowiednio zabezpieczone kontenery PHP-FPM oraz jasno określone procedury instalowania aktualizacji.

W przypadku istniejących aplikacji zazwyczaj realizujemy prace w trzech etapach:

  • Wstępny przegląd bezpieczeństwa. Sprawdzamy wersje oprogramowania, konfigurację, zależności oraz najbardziej narażone obszary aplikacji: logowanie, przesyłanie plików, panel administracyjny i interfejsy API. Taka analiza trwa zazwyczaj od 3 do 10 dni roboczych, a jej koszt wynosi orientacyjnie od 2000 do 6000 EUR, w zależności od wielkości projektu.
  • Szczegółowy audyt i testy penetracyjne. Łączymy ręczną analizę kodu z testami przeprowadzanymi zarówno z uwierzytelnieniem, jak i bez niego. Realizacja takiego audytu zajmuje zwykle od 2 do 5 tygodni. Koszt wynosi orientacyjnie od 6000 do 20 000 EUR, a w przypadku większych systemów może być wyższy.
  • Usuwanie podatności i aktualizacja oprogramowania. Eliminujemy wykryte problemy i, jeśli to konieczne, przeprowadzamy migrację z niewspieranych wersji PHP. Aktualizacja może potrwać od kilku tygodni w przypadku dobrze przetestowanych aplikacji Laravel lub Symfony do kilku miesięcy w przypadku rozbudowanych, starszych systemów (legacy).

Podane wartości są szacunkowe. Rzeczywisty zakres prac zależy przede wszystkim od jakości kodu, poziomu pokrycia testami oraz wykorzystywanej infrastruktury.

Nasza usługa w zakresie bezpieczeństwa i zgodności (Security & Compliance) może obejmować również stały monitoring oraz zarządzanie aktualizacjami zabezpieczeń. Dzięki temu kolejny problem w rodzaju PHP2SHELL staje się rutynowym zadaniem do rozwiązania, a nie sytuacją kryzysową dla Twojej firmy.

Podsumowanie: ochrona stron internetowych PHP przed atakami hakerów to ciągły proces

Ochrona stron internetowych opartych na PHP przed atakami hakerów nie polega na zastosowaniu jednego narzędzia czy zainstalowaniu pojedynczej aktualizacji. Wymaga kompleksowego podejścia, które obejmuje korzystanie ze wspieranych wersji oprogramowania, tworzenie kodu, który nigdy nie traktuje danych wejściowych jako zaufanych, odpowiednie zabezpieczenie serwera oraz stały monitoring umożliwiający reagowanie na zagrożenia w ciągu kilku godzin.

Podatności takie jak PHP2SHELL czy CVE-2024-4577 będą pojawiać się również w przyszłości. Bezpieczeństwo zachowają przede wszystkim te zespoły, które potrafią szybko wdrażać poprawki i ograniczać potencjalne szkody, nawet jeśli jakaś luka zostanie przeoczona.

Jeśli nie masz pewności, jak Twoja aplikacja PHP poradziłaby sobie z rzeczywistym atakiem, pozwól nam to sprawdzić.

Umów się na bezpłatną konsultację z Midapt. Przeanalizujemy Twoją infrastrukturę, wskażemy najpilniejsze zagrożenia i zaproponujemy realistyczny plan poprawy bezpieczeństwa Twojej aplikacji.

Najczęściej zadawane pytania dotyczące bezpieczeństwa stron internetowych opartych na PHP

Yes. Modern PHP 8.x is a mature, actively maintained language used by large platforms worldwide. Most PHP breaches come from outdated versions, vulnerable plugins and insecure custom code, not the language itself. With supported versions, a modern framework like Laravel or Symfony, secure coding practices and proper server hardening, PHP is as secure as any mainstream web technology.

Tak. Nowoczesne wersje PHP 8.x to dojrzała, aktywnie rozwijana technologia wykorzystywana przez duże platformy internetowe na całym świecie. Większość włamań na strony oparte na PHP wynika z korzystania z nieaktualnych wersji oprogramowania, podatnych wtyczek oraz niebezpiecznie napisanego kodu, a nie z samego języka PHP. Przy zastosowaniu wspieranych wersji PHP, nowoczesnego frameworka, takiego jak Laravel lub Symfony, bezpiecznych praktyk programistycznych oraz odpowiednio zabezpieczonej konfiguracji serwera, PHP zapewnia poziom bezpieczeństwa porównywalny z innymi popularnymi technologiami wykorzystywanymi do tworzenia aplikacji internetowych.

Sprawdź oficjalną stronę php.net – Supported Versions, na której znajduje się aktualna lista wersji PHP objętych aktywnym wsparciem oraz tych, które otrzymują wyłącznie poprawki bezpieczeństwa. Według stanu na 2026 rok PHP 8.1 i wszystkie starsze wersje zakończyły już cykl życia (End of Life) i nie otrzymują poprawek bezpieczeństwa. Aplikacje działające w środowisku produkcyjnym powinny korzystać z jednej ze wspieranych wersji PHP 8.x. Aktualizację należy przeprowadzić jeszcze przed zakończeniem okresu wsparcia bezpieczeństwa, aby uniknąć narażenia systemu na znane podatności.

Jednym z najczęstszych zagrożeń są zautomatyzowane ataki wykorzystujące znane podatności w nieaktualnych wtyczkach, motywach i zależnościach aplikacji. Do innych często spotykanych metod ataku należą: - SQL Injection – wstrzykiwanie złośliwych zapytań SQL w celu uzyskania dostępu do danych w bazie. - Cross-Site Scripting (XSS) – wstrzykiwanie złośliwych skryptów do stron internetowych. - Nieograniczone przesyłanie plików – wykorzystywanie mechanizmów uploadu do umieszczania na serwerze złośliwych skryptów, np. web shell. - Ataki brute force – wielokrotne próby odgadnięcia haseł do paneli administracyjnych. Większość takich ataków ma charakter oportunistyczny i jest przeprowadzana automatycznie na dużą skalę. Dlatego regularne aktualizowanie oprogramowania oraz stosowanie podstawowych zabezpieczeń serwera pozwala wyeliminować znaczną część potencjalnych zagrożeń.

Nie. Zapora aplikacyjna WAF (Web Application Firewall) stanowi dodatkową warstwę zabezpieczeń, która blokuje typowe wzorce ataków i może tymczasowo chronić aplikację przed znanymi podatnościami (tzw. virtual patching) do czasu wdrożenia właściwych poprawek. WAF nie jest jednak w stanie naprawić błędów w logice biznesowej aplikacji, nieprawidłowo skonfigurowanej kontroli dostępu ani problemów wynikających z ujawnienia danych uwierzytelniających. Dlatego WAF należy traktować jako element wielowarstwowej strategii bezpieczeństwa, uzupełniający bezpieczny kod, regularne aktualizacje i odpowiednie zabezpieczenie serwera, a nie jako rozwiązanie zastępujące te działania.

Koszt audytu bezpieczeństwa zależy przede wszystkim od wielkości aplikacji, stopnia jej złożoności oraz zakresu przeprowadzanych testów. Orientacyjne koszty przedstawiają się następująco: - Podstawowy przegląd bezpieczeństwa: w przypadku typowej strony internetowej opartej na PHP trwa zazwyczaj od 3 do 10 dni roboczych i kosztuje około 2000–6000 EUR. - Kompleksowy audyt bezpieczeństwa z analizą kodu i testami penetracyjnymi: zajmuje zwykle od 2 do 5 tygodni, a jego koszt wynosi około 6000–20 000 EUR. W przypadku rozbudowanych i złożonych systemów cena może być wyższa. Ostateczna wycena zależy od architektury aplikacji, jakości kodu, liczby wykorzystywanych komponentów oraz zakresu wymaganych testów.