Trenutno stanje: PHP2Shell. Dvije kritične PHP ranjivosti (CVSS 9.2) omogućuju zlonamjerni kod bez prijave. Zakrpe od 21. 10. 2026.Što sada učiniti →

Ugrađene sigurnosne funkcije PHP-a

PHP donosi sigurne gradivne elemente za lozinke, slučajne vrijednosti, maskiranje, kriptografiju i sesije. Tko ih dosljedno koristi, izbjegava najčešće pogreške u aplikacijama.

Stanje 5 min čitanjaPHP znanje

Ukratko: PHP za najčešće sigurnosne zadaće donosi gotove, provjerene funkcije: password_hash() za lozinke, random_bytes() i random_int() za tokene, htmlspecialchars() protiv cross-site scriptinga, pripremljene upite s PDO-om protiv SQL injectiona, hash_equals() za sigurne usporedbe i ekstenziju Sodium za kriptografiju. Tko te gradivne elemente dosljedno koristi, izbjegava većinu ranjivosti u aplikacijama. Protiv pogrešaka u samom PHP interpreteru, kao kod PHP2Shella, ne pomažu; ondje pomaže samo ažuriranje.

Zašto ugrađene PHP sigurnosne funkcije?

Pisati sigurnosni kod vlastitim snagama sklono je pogreškama. Vlastiti hash lozinke, samostalno izrađen generator tokena ili improvizirani filtar za HTML izlaze često izgledaju ispravno, a nisu. Ugrađene funkcije su dokumentirane, testirane i održavaju se PHP ažuriranjima.

Za donositelje odluka to znači: ne pitajte svoju agenciju ili razvojni tim jesu li sigurnosne funkcije izrađene samostalno, nego koriste li se standardne funkcije jezika. Tablica daje pregled.

Zadaća Funkcija Dostupno od Važna napomena
Spremanje lozinki password_hash(), password_verify() PHP 5.5 stupac do 255 znakova; bcrypt skraćuje na 72 bajta
Slučajni tokeni random_bytes(), random_int() PHP 7.0 nikad rand() ili mt_rand() za tajne
Slučajnost objektno orijentirano Random\Randomizer PHP 8.2 ista sigurnost, fleksibilnije sučelje
Maskiranje HTML izlaza htmlspecialchars() oduvijek zadane zastavice od 8.1 maskiraju i jednostruke navodnike
Usporedba u konstantnom vremenu hash_equals() PHP 5.6 korisnički unos kao drugi argument
Moderna kriptografija Sodium (sodium_*) PHP 7.2 umjesto vlastitog šifriranja
Tajne u stack traceovima #[\SensitiveParameter] PHP 8.2 vrijednost se ne pojavljuje u traceu
Provjera unosa filter_var() PHP 5.2 provjerava format, ne zamjenjuje maskiranje

Lozinke i tokeni

password_hash() stvara hash sa solju, a password_verify() ga provjerava. S PASSWORD_DEFAULT PHP trenutačno koristi bcrypt; od PHP-a 8.4 zadani faktor troška prema priručniku iznosi 12 umjesto 10. Budući da se zadani algoritam može promijeniti, priručnik preporučuje stupac u bazi podataka od 255 znakova. Kod bcrypta se lozinke odrezuju nakon 72 bajta, što treba imati na umu kod vrlo dugih lozinki-rečenica.

<?php
// Registracija
$hash = password_hash($passwort, PASSWORD_DEFAULT);

// Prijava, uključujući automatsko unaprjeđivanje starih hasheva
if (password_verify($eingabe, $hash)) {
    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        $hash = password_hash($eingabe, PASSWORD_DEFAULT); // spremiti iznova
    }
}

// Token za poveznicu za resetiranje lozinke
$token = bin2hex(random_bytes(32));

Za usporedbe tajni, primjerice potpisa, treba koristiti hash_equals(). Obična usporedba s === prema priručniku može vremenom izvršavanja odati od kojeg se mjesta dvije vrijednosti razlikuju. Opširnije: Sigurno spremanje lozinki u PHP-u i sigurni slučajni brojevi i tokeni.

Maskiranje izlaza i siguran upit u bazu podataka

Cross-site scripting nastaje kad korisnički unosi nefiltrirani završe u HTML-u. htmlspecialchars() pretvara posebne znakove u HTML entitete. Od PHP-a 8.1 zadane su zastavice ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401; prije toga jednostruki navodnici nisu se pretvarali. Tko mora podržavati starije verzije, zastavice navodi izričito.

SQL injection sprječavaju pripremljeni upiti. Vrijednosti se prenose odvojeno od SQL teksta i ne mogu promijeniti upit:

<?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');

Pojedinosti su na stranici Sprječavanje cross-site scriptinga u PHP-u i na stranici o SQL injectionu.

Provjera unosa drugi je, zaseban korak. filter_var() utvrđuje ima li vrijednost valjan format, primjerice e-adresa ili cijeli broj u dopuštenom rasponu. To, međutim, ne zamjenjuje maskiranje pri ispisu ni pripremljeni upit, jer i formalno valjane vrijednosti mogu sadržavati posebne znakove.

Tajne držati podalje od poruka o pogreškama

Podcijenjeno curenje podataka su stack traceovi. Kad se u funkciji dogodi pogreška, PHP zapisuje lanac poziva zajedno s argumentima. Ako se u njemu nalazi lozinka ili API ključ, završava u zapisniku. Od PHP-a 8.2 atribut #[\SensitiveParameter] označava takve parametre; njihova se vrijednost u traceu tada pojavljuje samo kao objekt SensitiveParameterValue.

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

Prema napomeni u priručniku atribut djeluje samo na konkretnoj implementaciji, a ne na metodi sučelja. Postavite ga stoga ondje gdje se kod stvarno izvršava.

Sesije: sigurne postavke i novi standardi

Sesije su čest cilj napada. Tri su postavke ključne: session.use_strict_mode=1 odbija ID-ove sesija koje poslužitelj nije sâm stvorio; session.cookie_httponly=1 sprječava pristup kolačiću sesije putem JavaScripta; session.cookie_samesite=Lax otežava slanje uz sadržaj sa stranih stranica. Prema prihvaćenom RFC-u upravo te tri vrijednosti postaju zadane s PHP-om 8.6. Do tada ih postavite sami, a i poslije toga izričito, kako konfiguracija ne bi ovisila o zadanoj vrijednosti.

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

Više u članku Osiguravanje sesija u PHP-u.

Što ugrađene funkcije ne mogu

PHP projekt u svojim je sigurnosnim smjernicama jasan: PHP nije sandbox. Zaobilaženja open_basedir ili disable_functions, zlonamjerni unosi u unserialize() i neprovjereni argumenti u funkcijama poput mysqli_query() ne smatraju se sigurnosnim ranjivostima PHP-a. Za operatere to znači: te su postavke korisno ojačavanje, ali nisu sigurnosna granica, a unserialize() s tuđim podacima nema što tražiti.

Druga točka tiče se PHP2Shella. CVE-2026-109618 i CVE-2026-109619 prema php.net omogućuju izvršavanje koda prije ili tijekom rada Vaše aplikacije; kod mod_php-a pokazan je exploit prije nego što se uopće izvrši kod aplikacije. Nijedna funkcija u Vašem kodu to ne može presresti. Sigurno programiranje i aktualna verzija PHP-a dvije su odvojene obveze i obje moraju biti ispunjene.

Kako PHP SOS konkretno pomaže?

U sigurnosnom auditu za PHP aplikacije ciljano provjeravamo:

  • Postupanje s lozinkama i tokenima: Koriste li se password_hash() i random_bytes() ili postoje vlastita rješenja?
  • Izlazi i upiti: Gdje unosi nefiltrirani završavaju u HTML-u, SQL-u ili shell naredbama?
  • Konfiguracija sesija: Jesu li postavljeni Strict Mode, HttpOnly, SameSite i Secure, i ne mogu li se prepisati?
  • Vrijeme izvođenja: Radi li podržana verzija PHP-a s ispravcima od 21. 10. 2026.?

Česta pitanja

Kako se lozinke u PHP-u ispravno spremaju?

Pomoću password_hash() i PASSWORD_DEFAULT, a provjerava se s password_verify(). Stupac u bazi podataka prema priručniku treba primiti do 255 znakova jer se zadani algoritam u budućnosti može promijeniti.

Je li rand() prikladan za tokene?

Ne. Za tokene, ključeve i poveznice za lozinke treba koristiti random_bytes() ili random_int(). Prema priručniku daju kriptografski sigurne slučajne vrijednosti.

Otkad je Sodium uključen u PHP?

Ekstenzija Sodium za modernu kriptografiju dio je PHP-a od verzije 7.2.0. Starije verzije mogle su je dodati samo putem PECL-a.

Štite li te funkcije od PHP2Shella?

Ne. Štite od pogrešaka u Vašoj aplikaciji. PHP2Shell je u samom interpreteru i zatvara se samo PHP ažuriranjem, nakon čega slijedi ponovno pokretanje svih PHP procesa.

Mijenjaju li se zadane postavke sesija u PHP-u 8.6?

Da, prema prihvaćenom RFC-u session.use_strict_mode i session.cookie_httponly prema zadanim se postavkama uključuju, a session.cookie_samesite postavlja se na Lax. Postojeće konfiguracije ipak biste trebali sami izričito postaviti.

Izvori

Hitni kontakt

Svaki sat se računa. Pišite nam odmah.

Ukratko opišite sustav, verziju PHP-a i opažanje. Javit ćemo Vam se, razjasniti situaciju i raditi na daljinu dok incident nije zaključen i dokumentiran.

Hitna pomoć