Lühidalt: PHP toob sagedasemate turvaülesannete jaoks kaasa valmis, kontrollitud funktsioonid: password_hash() paroolide jaoks, random_bytes() ja random_int() tokenite jaoks, htmlspecialchars() Cross-Site-Scriptingu vastu, ettevalmistatud päringud PDO-ga SQL-injektsiooni vastu, hash_equals() turvaliste võrdluste jaoks ja Sodiumi laiendus krüptograafia jaoks. Kes neid ehituskive järjekindlalt kasutab, väldib enamikku rakendusaukudest. PHP interpretaatori enda vigade vastu, nagu PHP2Shelli puhul, need ei aita; seal aitab ainult uuendus.
Miks PHP sisseehitatud turvafunktsioonid?
Turvakoodi ise kirjutada on veaaldis. Oma paroolihäsh, ise ehitatud tokenigeneraator või iseehitatud filter HTML-väljundite jaoks näevad sageli õiged välja ja ei ole seda siiski. Sisseehitatud funktsioonid on dokumenteeritud, testitud ja neid hooldatakse PHP uuendustega.
Otsustajale tähendab see: ärge küsige oma agentuurilt või arendustiimilt, kas turvafunktsioonid on ise ehitatud, vaid kas kasutatakse keele standardfunktsioone. Tabel annab ülevaate.
| Ülesanne | Funktsioon | Saadaval alates | Oluline märkus |
|---|---|---|---|
| Paroolide salvestamine | password_hash(), password_verify() |
PHP 5.5 | veerg kuni 255 märki; bcrypt lühendab 72 baidini |
| Juhuslikud tokenid | random_bytes(), random_int() |
PHP 7.0 | mitte kunagi rand() või mt_rand() saladuste jaoks |
| Juhuslikkus objektorienteeritult | Random\Randomizer |
PHP 8.2 | sama turvalisus, paindlikum liides |
| HTML-väljundi maskeerimine | htmlspecialchars() |
alati olnud | vaikelipud maskeerivad alates 8.1 ka ühekordsed jutumärgid |
| Ajakonstantne võrdlus | hash_equals() |
PHP 5.6 | kasutaja sisend teise argumendina |
| Kaasaegne krüptograafia | Sodium (sodium_*) |
PHP 7.2 | oma krüpteerimise asemel |
| Saladused stacktrace'ides | #[\SensitiveParameter] |
PHP 8.2 | väärtus ei ilmu trace'is |
| Sisendite kontrollimine | filter_var() |
PHP 5.2 | kontrollib vormingut, ei asenda maskeerimist |
Paroolid ja tokenid
password_hash() loob soolatud häshi, password_verify() kontrollib seda. Valikuga PASSWORD_DEFAULT kasutab PHP praegu bcrypt'i; alates PHP 8.4-st on vaikimisi kulutegur käsiraamatu järgi 12, mitte 10. Kuna vaikealgoritm võib muutuda, soovitab käsiraamat 255-märgilist andmebaasiveergu. Bcrypt'i puhul lõigatakse paroolid 72 baidi järel ära, mida tuleb väga pikkade paroolifraaside korral silmas pidada.
<?php
// Registreerimine
$hash = password_hash($passwort, PASSWORD_DEFAULT);
// Sisselogimine, kaasa arvatud vanade häshide automaatne uuendamine
if (password_verify($eingabe, $hash)) {
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
$hash = password_hash($eingabe, PASSWORD_DEFAULT); // uuesti salvestada
}
}
// Token parooli lähtestamise lingi jaoks
$token = bin2hex(random_bytes(32));
Saladuste, näiteks allkirja võrdlemiseks tuleb kasutada hash_equals(). Tavaline võrdlus operaatoriga === võib käsiraamatu järgi tööaja kaudu reeta, mitmendast kohast kaks väärtust erinevad. Põhjalikumalt: Paroolide turvaline salvestamine PHP-s ja turvalised juhuslikud arvud ja tokenid.
Väljundite maskeerimine ja andmebaasi turvaline pärimine
Cross-Site-Scripting tekib siis, kui kasutaja sisend satub filtreerimata HTML-i. htmlspecialchars() muudab erimärgid HTML-olemiteks. Alates PHP 8.1-st on vaikelipud ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401; varem ühekordseid jutumärke ei teisendatud. Kes peab vanemaid versioone toetama, märgib lipud selgesõnaliselt.
SQL-injektsiooni takistavad ettevalmistatud päringud. Väärtused edastatakse SQL-tekstist eraldi ja need ei saa päringut muuta:
<?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');
Üksikasjad on lehel Cross-Site-Scriptingu vältimine PHP-s ja SQL-injektsiooni käsitleval lehel.
Sisendite kontrollimine on teine, eraldi samm. filter_var() tuvastab, kas väärtusel on kehtiv vorming, näiteks e-posti aadress või täisarv lubatud vahemikus. See ei asenda aga väljundi maskeerimist ega ettevalmistatud päringut, sest ka vormiliselt kehtivad väärtused võivad sisaldada erimärke.
Saladuste hoidmine veateadetest eemal
Alahinnatud andmeleke on stacktrace'id. Kui funktsioonis tekib viga, logib PHP väljakutseahela koos argumentidega. Kui seal on parool või API võti, satub see logisse. Alates PHP 8.2-st märgib atribuut #[\SensitiveParameter] sellised parameetrid; nende väärtus ilmub trace'is siis ainult objektina SensitiveParameterValue.
<?php
function anmelden(string $benutzer, #[\SensitiveParameter] string $passwort): bool
{
// ... kontroll ...
throw new RuntimeException('Datenbank nicht erreichbar');
}
Käsiraamatu märkuse järgi mõjub atribuut ainult konkreetses realisatsioonis, mitte liidese meetodil. Seadke see seetõttu sinna, kus kood tegelikult töötab.
Sessioonid: turvalised sätted ja uued vaikeväärtused
Sessioonid on sage ründesihtmärk. Kolm sätet on kesksed: session.use_strict_mode=1 lükkab tagasi sessiooni ID-d, mida server ise ei loonud; session.cookie_httponly=1 takistab JavaScriptil sessiooniküpsisele ligipääsu; session.cookie_samesite=Lax raskendab selle kaasasaatmist võõrastelt lehtedelt. Vastu võetud RFC järgi muutuvad just need kolm väärtust PHP 8.6-ga vaikeseadeks. Seadke need seni ise, ja ka pärast seda selgesõnaliselt, et seadistus ei sõltuks vaikeväärtusest.
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
session.cookie_secure = 1
Lähemalt lehel Sessioonide kaitsmine PHP-s.
Mida sisseehitatud funktsioonid ei suuda
PHP projekt on oma turvapoliitikas selge: PHP ei ole liivakast. open_basedir või disable_functions möödapääsemised, pahatahtlikud sisendid funktsioonile unserialize() ja kontrollimata argumendid funktsioonidele nagu mysqli_query() ei loeta PHP turvaaukudeks. Haldajale tähendab see: need sätted on kasulik karastamine, kuid mitte turvapiir, ja unserialize()-il ei ole võõraste andmetega midagi pistmist.
Teine punkt puudutab PHP2Shelli. CVE-2026-109618 ja CVE-2026-109619 võimaldavad php.net andmetel koodi täitmist enne teie rakenduse käivitumist või selle ajal; mod_php puhul näidati ekspluateerimist enne, kui rakenduse kood üldse täidetakse. Ükski funktsioon teie koodis ei suuda seda kinni püüda. Turvaline programmeerimine ja ajakohane PHP versioon on kaks eraldi kohustust ning mõlemad tuleb täita.
Kuidas PHP SOS konkreetselt aitab?
PHP rakenduste turvaauditis kontrollime sihipäraselt:
- Parooli- ja tokenikäsitlus: Kas kasutatakse
password_hash()jarandom_bytes()või on olemas omaehitusi? - Väljundid ja päringud: Kus satuvad sisendid filtreerimata HTML-i, SQL-i või shelli käskudesse?
- Sessiooniseadistus: Kas Strict Mode, HttpOnly, SameSite ja Secure on seatud ning mitte ülekirjutatavad?
- Töökeskkond: Kas töötab toetatud PHP versioon koos 21.10.2026 parandustega?
Korduma kippuvad küsimused
Kuidas PHP-s paroole õigesti salvestada?
Funktsiooniga password_hash() ja PASSWORD_DEFAULT, kontrollitakse funktsiooniga password_verify(). Andmebaasi veerg peaks käsiraamatu järgi mahutama kuni 255 märki, sest vaikealgoritm võib tulevikus muutuda.
Kas rand() sobib tokenite jaoks?
Ei. Tokenite, võtmete ja paroolilinkide jaoks tuleb kasutada random_bytes() või random_int(). Need annavad käsiraamatu järgi krüptograafiliselt turvalisi juhuslikke väärtusi.
Millest alates on Sodium PHP-s olemas?
Sodiumi laiendus kaasaegse krüptograafia jaoks kuulub PHP juurde alates PHP 7.2.0-st. Vanemates versioonides sai seda täiendada ainult PECL kaudu.
Kas need funktsioonid kaitsevad PHP2Shelli eest?
Ei. Nad kaitsevad vigade eest teie rakenduses. PHP2Shell asub interpretaatoris endas ja suletakse ainult PHP uuendusega, millele järgneb kõigi PHP protsesside taaskäivitus.
Kas sessiooni vaikeväärtused muutuvad PHP 8.6-s?
Jah, vastu võetud RFC järgi lülitatakse session.use_strict_mode ja session.cookie_httponly vaikimisi sisse ning session.cookie_samesite seatakse väärtusele Lax. Olemasolevad seadistused peaksite siiski ise selgesõnaliselt seadma.