Proč bezpečnost v PHP není jen o frameworku
PHP pohání významnou část webu a jeho bezpečnost stojí na třech pilířích: správný návrh (threat modeling a bezpečnostní architektura), bezpečná implementace (obrana na všech vrstvách: vstup → logika → výstup) a provozní disciplína (konfigurace, aktualizace, monitoring). Bez ohledu na použitý framework (Laravel, Symfony, Nette, Slim aj.) platí, že musíte chránit hranice systému, data, identitu uživatele i integritu běhového prostředí.
Validace vstupů a normalizace dat
Vstup (HTTP parametry, JSON, hlavičky, cookies, uploady) musí být považován za nedůvěryhodný. Aplikujte whitelistovou validaci (formát, rozsah, délka, povolené znaky) a normalizaci (trim, canonicalizace) před dalším zpracováním. Nikdy nespoléhejte na validaci na straně klienta.
- Pro strukturovaná data využijte
filter_var(), validační knihovny (např. symfony/validator) a vlastní pravidla. - Pro identifikátory používejte pevné datové typy (int, uuid), nikoliv
stringbez omezení. - Neakceptujte dodatečná pole v JSON (proti „mass assignment“ používejte explicitní mapování povolených atributů).
Bezpečný výstup a prevence XSS
Cross-Site Scripting vzniká, když neescapovaný vstup skončí v HTML, JavaScriptu, CSS či URL. Zásady:
- Kontextové escapování: HTML, atribut, URL, JavaScript, CSS – každý kontext má jiná pravidla.
- Zapněte autoescapování v šablonách (Twig/Blade/Latte) a ručně escapujte dynamické části v JS (
json_encode($data, JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT)). - Omezte inline skripty a použijte Content-Security-Policy (CSP) s nonce (
Content-Security-Policy: script-src 'self' 'nonce-...'). - Sanitizace rich textu přes whitelist (např. HTML Purifier) – nikdy nepouštějte syrové HTML.
SQL Injection a práce s databází
Veškeré dotazy stavte pomocí prepared statements (PDO, Doctrine DBAL, Eloquent) s parametrizací. Nikdy neinterpolujte vstup do SQL řetězce.
- Používejte
PDO::prepare()abindValue()s odpovídajícími typy; vypněte emulované prepared statements (PDO::ATTR_EMULATE_PREPARES = false). - Pro ORM zajistěte, že query builder parametrizuje klauzule; dynamické názvy sloupců validujte proti whitelistu.
- Rozdělte role DB uživatelů (jen SELECT pro reporting, minimální práva pro aplikační uživatele).
CSRF ochrana a správa relací
Cross-Site Request Forgery se brání CSRF tokeny v mutačních požadavcích (POST/PUT/PATCH/DELETE). Doporučení:
- Generujte kryptograficky silné tokeny (
random_bytes(),bin2hex()) vázané na session; validujte je jednorázově (rotace). - Nastavte cookies HttpOnly, Secure, SameSite=Lax/Strict dle kontextu.
- Po přihlášení vždy regenerujte session ID (
session_regenerate_id(true)) – prevence fixation útoků. - U API preferujte bearer tokeny v
Authorizationhlavičce; pro SPA zvažte double-submit token nebo SameSite strategii.
Ověřování, autorizace a správa hesel
Bezpečné heslové hospodářství a řízení přístupu jsou klíčové:
- Hesla ukládejte pomocí
password_hash()(prioritně Argon2id nebo bcrypt) a ověřujte funkcípassword_verify(). Používejtepassword_needs_rehash()pro migrační rehash. - Implementujte omezení frekvence pokusů o přihlášení (rate limit), zamykání účtu po několika neúspěšných pokusech, audit přihlášení a vícefaktorovou autentifikaci (MFA) jako TOTP nebo WebAuthn.
- Autorizaci implementujte s principem deny-by-default, RBAC/ABAC s kontrolami v kontrolerech i na úrovni dotazů (scoped queries).
- Pro časové porovnání tokenů či otisků používejte
hash_equals()(ochrana proti timing útokům).
Bezpečné nahrávání souborů a práce s cestami
Nahrané soubory představují vysoké riziko:
- Ukládejte je mimo webroot a obsluhujte přes kontroler; pro veřejné servírování nastavte přísné Content-Type a Content-Disposition hlavičky.
- Validujte MIME typ (server-side), velikost, typ; generujte nové názvy souborů a adresářovou strukturu.
- Zabraňte RCE a path traversal: nikdy nepracujte s uživatelskými cestami přímo, používejte
basename(), mapujte ID→cesta, blokujte výskyt..a nulových bajtů. - Obrázky a mediální soubory zpracovávejte přes bezpečné knihovny; nespouštějte externí binární soubory bez whitelistu argumentů.
Deserializace, eval a vzdálené volání
Vyhněte se nebezpečným funkcím (eval, assert se stringem, unserialize na nedůvěryhodných datech). Pokud musíte deserializovat, používejte unserialize($data, ['allowed_classes' => false]) nebo raději JSON s explicitním mapováním. SOAP/RPC volání a webhooks validujte podepsanými požadavky a striktními timeouty.
SSRF, otevřené přesměrování a bezpečná práce s URL
Ověřujte a omezujte externí požadavky:
- Whitelist domén/hostitelů, zákaz interních IP rozsahů (169.254.0.0/16, 127.0.0.0/8, 10/8, 172.16/12, 192.168/16, link-local IPv6).
- DNS přeřešení po přesměrování a kontrola schémat (pouze
https). - U přesměrování z uživatelských parametrů používejte relativní cesty nebo mapu aliasů; jinak hrozí phishing (open redirect).
Bezpečná kryptografie
Neimplementujte vlastní šifrování. Používejte libsodium (sodium_crypto_aead_xchacha20poly1305_ietf_*) nebo openssl_encrypt s AEAD (AES-GCM). Klíče ukládejte mimo repozitář (např. do env, secret manageru), rotujte je a omezujte přístupy. Pro generování náhodných dat používejte random_bytes(), nikoli mt_rand().
HTTP hlavičky a ochrana v prohlížeči
Správná sada hlaviček zvyšuje základní úroveň bezpečnosti:
- Strict-Transport-Security (HSTS) pro vynucení HTTPS.
- Content-Security-Policy (CSP) s nonce či hashy, X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy.
- Frame-Ancestors (v CSP) proti clickjackingu.
Chybové stavy, logování a odhalování informací
V produkci vypněte výpis chyb do výstupu a logujte bezpečně:
display_errors = Off,log_errors = On, vlastní handler a korelace pomocí request-id.- Nikdy nelogujte citlivé údaje (hesla, tokeny, klíče). Maskujte osobní identifikovatelné informace (PII) dle GDPR.
- Uživatelům zobrazujte generické chybové stránky; podrobnosti pouze v logech a nástrojích pro observabilitu (Sentry, ELK, OpenTelemetry).
Konfigurace PHP a zabezpečení prostředí
Bezpečné výchozí hodnoty výrazně omezí riziko:
expose_php = Off,allow_url_fopen = Off(pokud není nezbytný),allow_url_include = Off.- Omezte
file_uploadsa velikosti (upload_max_filesize,post_max_size),max_input_vars, nastavte rozumné timeouty (max_execution_time,default_socket_timeout). - Na úrovni serveru zajistěte izolaci uživatelských účtů (FPM pool per app, chroot/kontainery), read-only přístup ke kódu, oddělené adresáře
var/atmp/s nastavenímnoexec.
Závislosti, dodavatelský řetězec a aktualizace
Composer je mocný nástroj, ale vyžaduje disciplínu:
- Uzamkněte verze (
composer.lockv repozitáři), sledujte security advisories a pravidelně aktualizujte (Dependabot, Renovate). - Používejte pouze důvěryhodné balíčky v minimální potřebné sadě a auditujte skripty v
composer.json(sekcescripts). - Pro produkci zapněte autoload-classmap authoritative pro lepší výkon a determinismus.
API bezpečnost: JWT, cookies a CORS
U API přes JWT dbejte na:
- Krátkou životnost tokenů (v řádu minut), podpis algoritmem HS256/RS256 se správou klíčů, kontrolu audience a issuer, validaci kid proti podvržení.
- Nepřidávejte do payloadu citlivá data; JWT je totiž pouze base64url zakódovaný, nikoliv šifrovaný.
- CORS: explicitně nastavte
Access-Control-Allow-Origin(nikoliv*pro požadavky s credentials), povolte jen potřebné metody a hlavičky, nikdy neaktivujteAccess-Control-Allow-Credentials: truespolečně s*.
Výkon vs. bezpečnost: rate limiting a ochrana proti brute-force
Implementujte ochrany proti zneužití:
- Rate limiting (např. token bucket, Redis) na citlivých koncových bodech (login, reset hesla, odesílání e-mailů).
- Detekce anomálií (neplatné tokeny, neobvyklé geografické polohy), šedé listiny a dynamická CAPTCHA aktivovaná po dosažení určitého prahu.
Bezpečnostní testování a CI/CD
Integrujte bezpečnost do pipeline:
- Statická analýza kódu (PHPStan/Psalm) s bezpečnostními pravidly, lint šablon (detekce porušení CSP, neescapovaných bloků).
- SAST/DAST skenery, audit závislostí (např. roave/security-advisories), unit a integrační testy pro scénáře autorizace.
- Secrets scanning (Git hooky, CI) a ochrany při pre-commit; podepisování release, SBOM (CycloneDX).
Šablonovací systémy a bezpečnost v praxi
Preferujte šablonovací systémy s autoescape (Twig/Latte/Blade). Zakazujte libovolné vykonávání kódu v šablonách, oddělte prezentační a aplikační logiku, využívejte komponenty místo přímého echo. U e-mailových šablon vždy escapujte a validujte URL.
Víceinstanční (multi-tenant) aplikace
Striktně vynucujte tenant scoping v každém dotazu (WHERE tenant_id = ?), validujte přístupové tokeny na úrovni tenanta, izolujte úložiště a cache klíče (tenant:<id>:* ). Vyhněte se insecure direct object references (IDOR) – nikdy nepoužívejte sekvenční ID bez kontroly vlastnictví.
Monitorování, audit a reakce na incidenty
Kromě logování provozujte metriky (latence, chybovost, 4xx/5xx kódy), bezpečnostní události (přihlášení, změny práv, administrace) a nastavte alerty. Mějte připravené runbooky pro reset tokenů, rotaci klíčů a nucené odhlášení. Pravidelně provádějte zálohy a test obnovy.
Checklist minimálních opatření
- Prepared statements všude; žádné dynamické SQL bez whitelistu.
- Autoescape šablon a CSP s nonce.
- Bezpečnost session: Secure, HttpOnly, SameSite; regenerace po přihlášení; CSRF tokeny.
- Hesla:
password_hash()(Argon2id/bcrypt), omezení frekvence přihlášení, MFA. - Nahrávání souborů mimo webroot, validace MIME, nová jména, žádné spouštění souborů.
- Bezpečná konfigurace PHP a web serveru; logování bez tajných dat.
- Aktualizace závislostí, audit balíčků, statická analýza v CI.



























