Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

Vstavané bezpečnostné funkcie PHP

PHP prináša bezpečné stavebné prvky pre heslá, náhodné hodnoty, maskovanie, kryptografiu a relácie. Kto ich dôsledne používa, vyhne sa najčastejším chybám aplikácií.

Stav 5 min čítaniaZnalosti o PHP

Stručne: PHP prináša pre najčastejšie bezpečnostné úlohy hotové, overené funkcie: password_hash() pre heslá, random_bytes() a random_int() pre tokeny, htmlspecialchars() proti cross-site scriptingu, pripravené dotazy s PDO proti SQL injection, hash_equals() pre bezpečné porovnávanie a rozšírenie Sodium pre kryptografiu. Kto tieto stavebné prvky dôsledne používa, vyhne sa väčšine zraniteľností aplikácií. Proti chybám v samotnom interpreteri PHP, ako pri PHP2Shell, nepomáhajú; tam pomáha iba aktualizácia.

Prečo vstavané bezpečnostné funkcie PHP?

Písať bezpečnostný kód sám je náchylné na chyby. Vlastný hash hesla, vlastnoručne postavený generátor tokenov alebo vlastný filter pre výstupy HTML často vyzerajú správne a napriek tomu nie sú. Vstavané funkcie sú zdokumentované, otestované a udržiavajú sa s aktualizáciami PHP.

Pre rozhodovateľov to znamená: nepýtajte sa svojej agentúry alebo vývojového tímu, či sa bezpečnostné funkcie písali samostatne, ale či sa používajú štandardné funkcie jazyka. Tabuľka dáva prehľad.

Úloha Funkcia Dostupná od Dôležitá poznámka
Ukladanie hesiel password_hash(), password_verify() PHP 5.5 stĺpec do 255 znakov; bcrypt skracuje na 72 bajtov
Náhodné tokeny random_bytes(), random_int() PHP 7.0 nikdy rand() alebo mt_rand() pre tajomstvá
Náhoda objektovo Random\Randomizer PHP 8.2 rovnaká bezpečnosť, flexibilnejšie rozhranie
Maskovanie výstupu HTML htmlspecialchars() odjakživa štandardné flagy od 8.1 maskujú aj jednoduché úvodzovky
Porovnanie v konštantnom čase hash_equals() PHP 5.6 vstup používateľa ako druhý argument
Moderná kryptografia Sodium (sodium_*) PHP 7.2 namiesto vlastného šifrovania
Tajomstvá v stacktraces #[\SensitiveParameter] PHP 8.2 hodnota sa v trace neobjaví
Kontrola vstupov filter_var() PHP 5.2 kontroluje formát, nenahrádza maskovanie

Heslá a tokeny

password_hash() vytvorí osolený hash, password_verify() ho overí. S PASSWORD_DEFAULT používa PHP momentálne bcrypt; od PHP 8.4 je štandardný nákladový faktor podľa príručky 12 namiesto 10. Pretože sa štandardný algoritmus môže zmeniť, príručka odporúča stĺpec databázy s 255 znakmi. Pri bcrypt sa heslá po 72 bajtoch odrežú, na čo treba myslieť pri veľmi dlhých prístupových frázach.

<?php
// Registrácia
$hash = password_hash($passwort, PASSWORD_DEFAULT);

// Prihlásenie, vrátane automatického zhodnotenia starých hashov
if (password_verify($eingabe, $hash)) {
    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        $hash = password_hash($eingabe, PASSWORD_DEFAULT); // uložiť znova
    }
}

// Token pre odkaz na obnovenie hesla
$token = bin2hex(random_bytes(32));

Na porovnávanie tajomstiev, napríklad podpisu, sa má používať hash_equals(). Bežné porovnanie pomocou === môže podľa príručky cez dobu behu prezradiť, od ktorého miesta sa dve hodnoty líšia. Podrobnejšie: Bezpečné ukladanie hesiel v PHP a bezpečné náhodné čísla a tokeny.

Maskovanie výstupov a bezpečné dotazovanie databázy

Cross-site scripting vzniká, keď sa vstupy používateľa dostanú do HTML nefiltrované. htmlspecialchars() premieňa špeciálne znaky na entity HTML. Od PHP 8.1 sú štandardné flagy ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401; predtým sa jednoduché úvodzovky neprevádzali. Kto musí podporovať staršie verzie, uvedie flagy výslovne.

SQL injection zabraňujú pripravené dotazy. Hodnoty sa prenášajú oddelene od textu SQL a dotaz nemôžu zmeniť:

<?php
$stmt = $pdo->prepare('SELECT id, name FROM kunden WHERE email = :email');
$stmt->execute(['email' => $email]);
$kunde = $stmt->fetch();

echo htmlspecialchars($kunde['name'] ?? '', ENT_QUOTES, 'UTF-8');

Podrobnosti sú v Prevencia cross-site scriptingu v PHP a na stránke o SQL injection.

Kontrola vstupov je druhý, samostatný krok. filter_var() zisťuje, či má hodnota platný formát, napríklad e-mailovú adresu alebo celé číslo v povolenom rozsahu. To však nenahrádza maskovanie pri výstupe ani pripravený dotaz, pretože aj formálne platné hodnoty môžu obsahovať špeciálne znaky.

Tajomstvá držať mimo chybových hlásení

Nedocenený únik údajov sú stacktraces. Ak nastane vo funkcii chyba, PHP zapíše reťazec volaní vrátane argumentov. Ak je v ňom heslo alebo kľúč API, skončí v logu. Od PHP 8.2 označuje takéto parametre atribút #[\SensitiveParameter]; ich hodnota sa potom v trace objaví len ako objekt SensitiveParameterValue.

<?php
function anmelden(string $benutzer, #[\SensitiveParameter] string $passwort): bool
{
    // ... kontrola ...
    throw new RuntimeException('Datenbank nicht erreichbar');
}

Podľa poznámky v príručke atribút pôsobí iba na konkrétnej implementácii, nie na metóde rozhrania. Nastavte ho preto tam, kde kód skutočne beží.

Relácie: bezpečné nastavenia a nové štandardy

Relácie sú častým cieľom útokov. Tri nastavenia sú kľúčové: session.use_strict_mode=1 odmieta ID relácií, ktoré server sám nevytvoril; session.cookie_httponly=1 bráni prístupu k cookie relácie cez JavaScript; session.cookie_samesite=Lax sťažuje spoluodosielanie pri cudzích stránkach. Podľa prijatého RFC sa práve tieto tri hodnoty stanú s PHP 8.6 štandardom. Nastavte ich dovtedy sami, a aj potom výslovne, aby konfigurácia nezávisela od štandardu.

session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
session.cookie_secure = 1

Viac v Zabezpečenie relácií v PHP.

Čo vstavané funkcie nezvládnu

Projekt PHP je vo svojich bezpečnostných zásadách jasný: PHP nie je sandbox. Obchádzanie open_basedir alebo disable_functions, zlomyseľné vstupy do unserialize() a neoverené argumenty do funkcií ako mysqli_query() sa nepovažujú za bezpečnostné zraniteľnosti PHP. Pre prevádzkovateľov to znamená: tieto nastavenia sú užitočným sprísnením, ale nie bezpečnostnou hranicou, a unserialize() nemá s cudzími údajmi nič spoločné.

Druhý bod sa týka PHP2Shell. CVE-2026-109618 a CVE-2026-109619 podľa php.net umožňujú vykonanie kódu skôr alebo počas toho, ako beží vaša aplikácia; pri mod_php bol predvedený exploit skôr, než sa vôbec vykoná aplikačný kód. Žiadna funkcia vo vašom kóde to nemôže zachytiť. Bezpečné programovanie a aktuálna verzia PHP sú dve oddelené povinnosti a musia byť splnené obe.

Ako PHP SOS konkrétne pomáha?

V bezpečnostnom audite aplikácií PHP cielene kontrolujeme:

  • Spracovanie hesiel a tokenov: Používajú sa password_hash() a random_bytes(), alebo existujú vlastné konštrukcie?
  • Výstupy a dotazy: Kde sa vstupy dostanú nefiltrované do HTML, SQL alebo príkazov shellu?
  • Konfigurácia relácií: Sú nastavené Strict Mode, HttpOnly, SameSite a Secure a nedajú sa prepísať?
  • Runtime: Beží podporovaná verzia PHP s opravami z 21. 10. 2026?

Časté otázky

Ako sa v PHP správne ukladajú heslá?

Pomocou password_hash() a PASSWORD_DEFAULT, kontroluje sa pomocou password_verify(). Stĺpec databázy by mal podľa príručky pojať až 255 znakov, pretože sa štandardný algoritmus môže v budúcnosti zmeniť.

Hodí sa rand() na tokeny?

Nie. Na tokeny, kľúče a odkazy na obnovenie hesla sa majú používať random_bytes() alebo random_int(). Podľa príručky poskytujú kryptograficky bezpečné náhodné hodnoty.

Odkedy je Sodium súčasťou PHP?

Rozšírenie Sodium pre modernú kryptografiu je súčasťou PHP od verzie 7.2.0. Staršie verzie ho mohli doplniť iba cez PECL.

Chránia tieto funkcie pred PHP2Shell?

Nie. Chránia pred chybami vo vašej aplikácii. PHP2Shell sídli v samotnom interpreteri a uzavrie sa iba aktualizáciou PHP, po ktorej nasleduje reštart všetkých procesov PHP.

Zmenia sa štandardy relácií v PHP 8.6?

Áno, podľa prijatého RFC sa session.use_strict_mode a session.cookie_httponly štandardne zapnú a session.cookie_samesite sa nastaví na Lax. Existujúce konfigurácie by ste mali napriek tomu nastaviť sami výslovne.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc