Ukratko: Za sigurnost API-ja u PHP-u ponajprije se računa pet točaka: samo HTTPS, autentifikacija na svakoj nejavnoj krajnjoj točki, provjera ovlasti za svaki pojedinačni objekt, stroge granice za metodu, tip sadržaja i veličinu zahtjeva te kratke poruke o pogreškama bez internih pojedinosti. Tome se pridodaju ograničenje stope i zapisnik sigurnosno relevantnih događaja. Protiv ranjivosti u samom PHP interpreteru poput PHP2Shella to ne pomaže; za to je potreban PHP update.
Sučelje iza web-stranice
Mnoge su tvrtke u tjednu nakon 21. 10. 2026. provjeravale svoje web-stranice. Sučelja iza njih rjeđe su bila na popisu. A upravo se tamo odvijaju osjetljivi procesi: aplikacija korisničkog portala dohvaća račune, sustav za upravljanje robom upisuje zalihe u shop, partner prijavljuje narudžbe putem webhooka. Ti su API-ji često brzo izgrađeni, za jednu jedinu svrhu, i nakon toga nikad više pregledani.
API nema sučelje koje čini pogreške vidljivima. Nedostajuća provjera ovlasti u svakodnevici nikome ne upada u oči sve dok svi klijenti dohvaćaju samo ono što smiju. Napadač pak isprobava upravo ono što nije predviđeno.
Prvi korak je stoga popis stanja. Koje krajnje točke uopće postoje? Često se nalaze stare verzije poput /api/v1/ koje nakon prelaska na /v2/ nikad nisu isključene, testne krajnje točke iz razvoja ili javno dostupan opis sučelja koji navodi interne funkcije. Svaku krajnju točku koja se više ne treba, treba isključiti. Svaka koja ostaje treba odgovornu osobu.
Sigurnost API-ja u PHP-u: osnovna pravila
OWASP REST Security Cheat Sheet sažima dokazana pravila. Za PHP projekte mogu se prevesti u kratak popis:
- Samo HTTPS. Tokeni i pristupni podaci nikad se ne smiju prenositi nešifrirani.
- Svaka krajnja točka provjerava sama. Autentifikacija se može odvijati središnje, a odluka o pristupu pada na krajnjoj točki.
- Ovlast po objektu. Ne samo „prijavljen je“, nego „smije upravo taj zapis“.
- Utvrditi dopuštene metode. Što nije izričito dopušteno, odbija se s 405.
- Provjeriti tip sadržaja i veličinu. Pogrešan tip daje 415, preveliki zahtjevi 413.
- Validirati unose. Tip, duljina, format i raspon vrijednosti, na strani poslužitelja.
- Bez tajni u URL-ovima. Tokeni i ključevi pripadaju u zaglavlja, a ne u query string.
- Kratke pogreške. Bez stack traceova, putanja ili SQL poruka prema klijentu.
- Ograničenje stope. Na previše zahtjeva odgovara se s 429.
- Odvojiti administrativne krajnje točke. Nisu javno dostupne ili samo uz jaku prijavu.
Ovlast po objektu: najčešća pogreška
Primjer problem čini opipljivim. Krajnja točka isporučuje račune pod /api/rechnungen/{id}. Provjerava se postoji li valjan token. Ne provjerava se pripada li račun kupcu iz tokena. Tko svoj broj računa poveća za jedan, vidi račun susjeda.
Rješenje je jednostavno, a ipak se mora provesti na svakom mjestu: sam upit ograničava na ovlašteno područje.
<?php
// Dopustiti samo metodu GET
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
http_response_code(405);
header('Allow: GET');
exit;
}
$kundeId = $auth->kundeId(); // iz provjerenog tokena
$id = filter_var($routeId, FILTER_VALIDATE_INT);
if ($id === false) {
http_response_code(400);
exit;
}
// Ovlast je u upitu: samo vlastiti računi
$stmt = $pdo->prepare('SELECT nummer, betrag, datum FROM rechnungen WHERE id = ? AND kunde_id = ?');
$stmt->execute([$id, $kundeId]);
$rechnung = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$rechnung) {
http_response_code(404); // ne otkrivati postoji li ID
exit;
}
header('Content-Type: application/json');
echo json_encode($rechnung, JSON_THROW_ON_ERROR);
Upit s rezerviranim mjestima istodobno štiti od SQL injectiona, vidi Spriječiti SQL injection u PHP-u. Kako PHP stavlja na raspolaganje podatke zahtjeva poput metode, zaglavlja i tijela, objašnjava Superglobals: $_GET, $_POST, $_FILES i ostali.
Ispravno provjeravati tokene
Mnogi API-ji rade s JSON Web Tokenima. OWASP Cheat Sheet za to navodi jasna pravila: tokeni moraju biti potpisani, nepotpisani tokeni se odbijaju, a algoritam za provjeru utvrđuje se na poslužitelju, a ne preuzima iz tokena. Izdavatelj, ciljna skupina i vrijeme isteka također pripadaju provjeri. Za to koristite održavanu biblioteku umjesto vlastitih izvedbi.
Vlastiti tokeni, primjerice za webhookove ili jednokratne poveznice, moraju potjecati iz kriptografski sigurnog generatora slučajnih brojeva i uspoređivati se u konstantnom vremenu. Kako to ide u PHP-u, pokazuje Sigurni slučajni brojevi i tokeni u PHP-u.
Svakom klijentu i svakom partneru dajte vlastiti ključ s točno onim pravima koja su mu potrebna. Tada se procurjeli ključ može pojedinačno blokirati, a da se ne prekinu sve ostale veze.
Postaviti granice: veličina, tip i tempo
API bi trebao prihvaćati samo ono što očekuje. To počinje tipom sadržaja: krajnja točka koja obrađuje JSON odbija sve ostalo. Maksimalnu veličinu zahtjeva ograničavate na više razina, u web-poslužitelju i u PHP-u putem post_max_size. Ta granica pripada i privremenim mjerama koje je php.net naveo za PHP2Shell. Kako je smisleno odabrati, opisuje Smisleno ograničiti post_max_size i upload_max_filesize.
Ograničenje stope štiti od isprobavanja identifikatora i od preopterećenja. Može se provesti u web-poslužitelju, u proxyju ispred ili u aplikaciji. Važno je da granice vrijede po ključu ili korisniku, a ne samo po IP adresi.
Za API-je koji se pozivaju izravno iz preglednika dolazi CORS, dakle pravila koje strane web-stranice smiju slati zahtjeve. Ta zaglavlja postavite samo ako su takvi pozivi doista predviđeni, a dopuštena podrijetla navedite pojedinačno umjesto da dopuštate svako podrijetlo. Zamjenski znak koji dopušta sve web-stranice kod krajnjih točaka s prijavom gotovo je uvijek pogreška.
Na kraju zapisnik: neuspjele prijave, odbijeni tokeni i uskraćeni pristupi pripadaju u zapisnik, a sami tokeni ne. Bez tih unosa napad na API ostaje nevidljiv.
Kako PHP SOS konkretno pomaže?
- Bilježimo sva sučelja Vaših PHP sustava, i zaboravljena i interna, te provjeravamo koja su javno dostupna.
- Čitamo logiku ovlasti i ciljano testiramo mogu li se dohvatiti tuđi zapisi.
- Granice za veličinu, tip i tempo postavljamo u web-poslužitelju i PHP-u i usklađujemo ih s Vašim klijentima.
- Za sveobuhvatnu provjeru izvana to kombiniramo sa sigurnosnim auditom i penetracijskim testom.
Zaključak: API je siguran koliko i njegova najnemarnija krajnja točka. Tko provjerava ovlasti po objektu, postavlja jasne granice i poruke o pogreškama drži kratkima, zatvara najčešće ranjivosti mnogo prije nego ih netko ciljano potraži.
Česta pitanja
Je li API ključ dovoljna zaštita?
Za osjetljive podatke nije. API ključ obično identificira aplikaciju, a ne korisnika, i lako se prosljeđuje. OWASP REST Security Cheat Sheet savjetuje da se API ključevi ne koriste kao jedina zaštita za osjetljive resurse.
Što je ovlast po objektu i zašto tako često nedostaje?
Misli se na provjeru smije li prijavljeni korisnik vidjeti ili mijenjati upravo taj zapis. Često nedostaje jer razvojni inženjeri provjeravaju samo je li netko uopće prijavljen. Tada je dovoljno promijeniti identifikator u URL-u da bi se dohvatili tuđi podaci.
Štiti li dobro osiguran API od PHP2Shella?
Ne. PHP2Shell se nalazi u PHP interpreteru i djeluje kod pogođenih načina rada prije nego Vaš kod uopće radi. Protiv toga pomaže samo PHP update s ponovnim pokretanjem. Ograničenja veličine zahtjeva ipak su smislena i pripadaju privremenim mjerama s php.net-a.
Koje statusne kodove API treba vraćati kod sigurnosnih pogrešaka?
Uobičajeni su 401 bez valjane prijave, 403 kod nedostajuće ovlasti, 405 kod nedopuštene metode, 413 kod prevelikog zahtjeva, 415 kod pogrešnog tipa sadržaja i 429 kod previše zahtjeva. Sam odgovor pritom ostaje kratak i bez internih pojedinosti.