# Įmontuotos PHP saugumo funkcijos

> PHP saugumo funkcijų apžvalga: slaptažodžiai, atsitiktinumas, maskavimas, kriptografija, sesijos ir kur jų ribos esant tokioms spragoms kaip PHP2Shell.

Šaltinis: https://phpsos.de/lt/php/eingebaute-sicherheitsfunktionen/  
Būsena: 2026-10-25  
Teikėjas: PHP SOS, PHP avarinė pagalba ir serverio sauga. Skubi pagalba per „WhatsApp“: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20reikia%20pagalbos%20su%20m%C5%ABs%C5%B3%20PHP%20serveriu.%20%C4%AEmon%C4%97%3A%20%E2%80%A6%20Svetain%C4%97%3A%20%E2%80%A6

**Trumpai:** PHP dažniausioms saugumo užduotims pateikia paruoštas, patikrintas funkcijas: `password_hash()` slaptažodžiams, `random_bytes()` ir `random_int()` žetonams, `htmlspecialchars()` nuo kryžminio svetainių skriptų vykdymo (XSS), parengtas užklausas su PDO nuo SQL injekcijos, `hash_equals()` saugiems palyginimams ir Sodium plėtinį kriptografijai. Kas šiuos elementus naudoja nuosekliai, išvengia daugumos programų spragų. Nuo klaidų paties PHP interpretatoriuje, kaip PHP2Shell atveju, jie nepadeda; ten padeda tik atnaujinimas.

## Kodėl įmontuotos PHP saugumo funkcijos?

Pačiam rašyti saugumo kodą linkę klysti. Nuosavas slaptažodžio maišos algoritmas, pačių sukurtas žetonų generatorius ar pačių sukurtas HTML išvesčių filtras dažnai atrodo teisingai, bet tokie nėra. Įmontuotos funkcijos yra dokumentuotos, išbandytos ir prižiūrimos su PHP atnaujinimais.

Sprendimų priėmėjams tai reiškia: neklauskite savo agentūros ar kūrimo komandos, ar saugumo funkcijos buvo kuriamos pačių, o klauskite, ar naudojamos standartinės kalbos funkcijos. Lentelėje pateikta apžvalga.

| Užduotis | Funkcija | Prieinama nuo | Svarbi pastaba |
|---|---|---|---|
| Slaptažodžių saugojimas | `password_hash()`, `password_verify()` | PHP 5.5 | stulpelis iki 255 simbolių; bcrypt sutrumpina iki 72 baitų |
| Atsitiktiniai žetonai | `random_bytes()`, `random_int()` | PHP 7.0 | niekada `rand()` ar `mt_rand()` paslaptims |
| Atsitiktinumas objektiškai | `Random\Randomizer` | PHP 8.2 | tas pats saugumas, lankstesnė sąsaja |
| HTML išvesties maskavimas | `htmlspecialchars()` | nuo seno | numatytosios vėliavėlės nuo 8.1 maskuoja ir pavienes kabutes |
| Palyginimas pastoviu laiku | `hash_equals()` | PHP 5.6 | naudotojo įvestis kaip antrasis argumentas |
| Šiuolaikinė kriptografija | Sodium (`sodium_*`) | PHP 7.2 | vietoj savo šifravimo |
| Paslaptys steko pėdsakuose | `#[\SensitiveParameter]` | PHP 8.2 | reikšmė pėdsake nerodoma |
| Įvesčių tikrinimas | `filter_var()` | PHP 5.2 | tikrina formatą, neatstoja maskavimo |

## Slaptažodžiai ir žetonai

`password_hash()` sukuria pasūdytą maišą, `password_verify()` ją patikrina. Su `PASSWORD_DEFAULT` PHP šiuo metu naudoja bcrypt; nuo PHP 8.4 numatytasis kainos veiksnys, pasak vadovo, yra 12, o ne 10. Kadangi numatytasis algoritmas gali pasikeisti, vadovas rekomenduoja 255 simbolių duomenų bazės stulpelį. Naudojant bcrypt slaptažodžiai nupjaunami po 72 baitų, į ką reikia atsižvelgti labai ilgų slaptažodžių frazių atveju.

```php
<?php
// Registracija
$hash = password_hash($passwort, PASSWORD_DEFAULT);

// Prisijungimas, įskaitant automatinį senų maišų atnaujinimą
if (password_verify($eingabe, $hash)) {
    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        $hash = password_hash($eingabe, PASSWORD_DEFAULT); // išsaugoti iš naujo
    }
}

// Žetonas slaptažodžio atkūrimo nuorodai
$token = bin2hex(random_bytes(32));
```

Paslapčių, pavyzdžiui, parašo, palyginimui reikia naudoti `hash_equals()`. Įprastas palyginimas su `===`, pasak vadovo, per vykdymo trukmę gali išduoti, nuo kurios vietos dvi reikšmės skiriasi. Išsamiau: [Saugus slaptažodžių saugojimas PHP](https://phpsos.de/lt/blog/passwoerter-in-php-speichern/) ir [saugūs atsitiktiniai skaičiai ir žetonai](https://phpsos.de/lt/blog/sichere-tokens-php/).

## Išvesčių maskavimas ir saugios užklausos duomenų bazei

Kryžminio svetainių skriptų vykdymas (XSS) atsiranda, kai naudotojo įvestys nefiltruotos patenka į HTML. `htmlspecialchars()` specialiuosius simbolius paverčia HTML esybėmis. Nuo PHP 8.1 numatytosios vėliavėlės yra `ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401`; anksčiau pavienės kabutės nebuvo konvertuojamos. Kas turi palaikyti senesnes versijas, vėliavėles nurodo aiškiai.

SQL injekciją užkerta parengtos užklausos. Reikšmės perduodamos atskirai nuo SQL teksto ir užklausos pakeisti negali:

```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');
```

Išsamiau skyriuje [Kryžminio svetainių skriptų vykdymo (XSS) prevencija PHP](https://phpsos.de/lt/ratgeber/xss-php/) ir SQL injekcijos puslapyje.

Įvesčių patikra yra antras, atskiras žingsnis. `filter_var()` nustato, ar reikšmė turi tinkamą formatą, pavyzdžiui, el. pašto adresą ar sveikąjį skaičių leistinoje srityje. Tačiau tai neatstoja maskavimo išvedant ir parengtos užklausos, nes ir formaliai tinkamos reikšmės gali turėti specialiųjų simbolių.

## Paslapčių nelaikymas klaidų pranešimuose

Nepakankamai vertinamas duomenų nutekėjimas yra steko pėdsakai. Įvykus klaidai funkcijoje, PHP užprotokoluoja iškvietimų grandinę kartu su argumentais. Jei joje yra slaptažodis ar API raktas, jis patenka į žurnalą. Nuo PHP 8.2 atributas `#[\SensitiveParameter]` tokius parametrus pažymi; jų reikšmė pėdsake tuomet rodoma tik kaip objektas `SensitiveParameterValue`.

```php
<?php
function anmelden(string $benutzer, #[\SensitiveParameter] string $passwort): bool
{
    // ... patikra ...
    throw new RuntimeException('Datenbank nicht erreichbar');
}
```

Pasak vadovo pastabos, atributas veikia tik konkrečiame įgyvendinime, o ne sąsajos metode. Todėl nustatykite jį ten, kur kodas iš tikrųjų vykdomas.

## Sesijos: saugūs nustatymai ir nauji numatytieji

Sesijos yra dažnas atakų taikinys. Trys nustatymai pagrindiniai: `session.use_strict_mode=1` atmeta sesijos ID, kurių serveris pats nesukūrė; `session.cookie_httponly=1` neleidžia JavaScript pasiekti sesijos slapuko; `session.cookie_samesite=Lax` apsunkina siuntimą kartu su užklausomis iš svetimų svetainių. Pasak priimto RFC, būtent šios trys reikšmės su PHP 8.6 taps numatytosiomis. Iki to laiko nustatykite jas patys, o ir po to aiškiai, kad konfigūracija nepriklausytų nuo numatytųjų reikšmių.

```ini
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
session.cookie_secure = 1
```

Daugiau skyriuje [Sesijų apsauga PHP](https://phpsos.de/lt/ratgeber/session-sicherheit-php/).

## Ko įmontuotos funkcijos neatlieka

PHP projektas savo saugumo politikoje aiškus: PHP nėra smėlio dėžė (sandbox). `open_basedir` ar `disable_functions` apėjimai, kenkėjiški duomenys `unserialize()` ir nepatikrinti argumentai funkcijoms, tokioms kaip `mysqli_query()`, nelaikomi PHP saugumo spragomis. Operatoriams tai reiškia: šie nustatymai yra naudingas sutvirtinimas, bet ne saugumo riba, o `unserialize()` su svetimais duomenimis neturi nieko bendra.

Antras punktas liečia PHP2Shell. Pasak php.net, CVE-2026-109618 ir CVE-2026-109619 leidžia vykdyti kodą prieš jūsų programai pasileidžiant ar jai veikiant; su mod_php buvo parodytas exploit dar prieš vykdant bet kokį programos kodą. Jokia jūsų kodo funkcija to sustabdyti negali. Saugus programavimas ir nauja PHP versija yra dvi atskiros pareigos, ir abi turi būti įvykdytos.

## Kaip PHP SOS padeda konkrečiai?

[PHP programų saugumo audito](https://phpsos.de/lt/leistungen/sicherheitsaudit-penetrationstest/) metu tikslingai tikriname:

- **Slaptažodžių ir žetonų tvarkymas:** ar naudojami `password_hash()` ir `random_bytes()`, ar yra savadarbių sprendimų?
- **Išvestys ir užklausos:** kur įvestys nefiltruotos patenka į HTML, SQL ar shell komandas?
- **Sesijų konfigūracija:** ar nustatyti Strict Mode, HttpOnly, SameSite ir Secure ir ar jų negalima perrašyti?
- **Vykdymo aplinka:** ar veikia palaikoma PHP versija su 2026-10-21 ištaisymais?


## Dažni klausimai

**Kaip PHP teisingai saugoti slaptažodžius?**  
Su password_hash() ir PASSWORD_DEFAULT, tikrinama su password_verify(). Pasak vadovo, duomenų bazės stulpelis turėtų talpinti iki 255 simbolių, nes numatytasis algoritmas ateityje gali pasikeisti.

**Ar rand() tinka žetonams?**  
Ne. Žetonams, raktams ir slaptažodžio atkūrimo nuorodoms reikia naudoti random_bytes() arba random_int(). Pasak vadovo, jos pateikia kriptografiškai saugias atsitiktines reikšmes.

**Nuo kada Sodium yra PHP?**  
Sodium plėtinys šiuolaikinei kriptografijai yra PHP dalis nuo PHP 7.2.0. Senesnėse versijose jį buvo galima įdiegti tik per PECL.

**Ar šios funkcijos saugo nuo PHP2Shell?**  
Ne. Jos saugo nuo klaidų jūsų programoje. PHP2Shell slypi pačiame interpretatoriuje ir uždaroma tik PHP atnaujinimu, po kurio visi PHP procesai paleidžiami iš naujo.

**Ar sesijų numatytieji nustatymai keisis PHP 8.6?**  
Taip, pasak priimto RFC, session.use_strict_mode ir session.cookie_httponly bus įjungti pagal numatymą, o session.cookie_samesite nustatytas į Lax. Esamas konfigūracijas vis tiek verta aiškiai nustatyti patiems.

## Šaltiniai

- [PHP vadovas: password_hash()](https://www.php.net/manual/en/function.password-hash.php)
- [PHP vadovas: random_bytes()](https://www.php.net/manual/en/function.random-bytes.php)
- [PHP vadovas: 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/)
