# Vstavané bezpečnostné funkcie PHP

> Bezpečnostné funkcie PHP v prehľade: heslá, náhoda, maskovanie, kryptografia, relácie a kde sú ich hranice pri zraniteľnostiach ako PHP2Shell.

Zdroj: https://phpsos.de/sk/php/eingebaute-sicherheitsfunktionen/  
Stav: 25.10.2026  
Poskytovateľ: PHP SOS, Núdzová pomoc pri PHP a bezpečnosť serverov. Okamžitá pomoc cez WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20de%C5%88%2C%20PHP%20SOS%2C%20potrebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20serverom%20s%20PHP.%20Spolo%C4%8Dnos%C5%A5%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**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
<?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](https://phpsos.de/sk/blog/passwoerter-in-php-speichern/) a [bezpečné náhodné čísla a tokeny](https://phpsos.de/sk/blog/sichere-tokens-php/).

## 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
<?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](https://phpsos.de/sk/ratgeber/xss-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
<?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.

```ini
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](https://phpsos.de/sk/ratgeber/session-sicherheit-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](https://phpsos.de/sk/leistungen/sicherheitsaudit-penetrationstest/) 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

- [Príručka PHP: password_hash()](https://www.php.net/manual/en/function.password-hash.php)
- [Príručka PHP: random_bytes()](https://www.php.net/manual/en/function.random-bytes.php)
- [Príručka PHP: hash_equals()](https://www.php.net/manual/en/function.hash-equals.php)
- [PHP RFC: Secure Session Configuration Defaults](https://wiki.php.net/rfc/session_security_defaults)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
