Preskočiť na obsah
Bezpečnosť Backend 8. máj 2026 · 14 min čítania

PHP Security best practices 2026 — checklist pre každý projekt

Viac než 80 % PHP aplikácií obsahuje aspoň jednu kritickú bezpečnostnú chybu podľa správy OWASP z roku 2025. Nie preto, že by vývojári nevedeli programovať — ale preto, že bezpečnosť sa pridáva neskoro, keď je refaktor príliš drahý. Tento checklist pokrýva všetko, čo treba vyriešiť ešte pred spustením projektu.

DC

Dušan Chlpek

Senior PHP vývojár · GEAR s.r.o. · 25+ rokov praxe

1. SQL injection — základ, ktorý stále zabíja projekty

SQL injection zostáva na prvom mieste OWASP Top 10 už roky. V roku 2026 nie je výhovorka — každý ORM a databázová knižnica má zabudovanú ochranu, ak ju správne použijete.

<?php
// CHYBA — priama interpolácia do SQL
$products = DB::select("SELECT * FROM products WHERE name = '{$_GET['name']}'");

// SPRÁVNE — parameterized query (PDO)
$stmt = $pdo->prepare("SELECT * FROM products WHERE name = ?");
$stmt->execute([$_GET['name']]);

// SPRÁVNE — Laravel Eloquent (automatická ochrana)
$products = Product::where('name', $request->name)->get();

// SPRÁVNE — Raw SQL v Laraveli s bindingmi
$products = DB::select("SELECT * FROM products WHERE category = ? AND price < ?", [
    $request->category,
    $request->max_price,
]);
Pozor na Raw expressions: DB::raw(), whereRaw() a podobné metódy v Eloquente nevykonávajú escaping. Ak do nich vkladáte user input, použite vždy parametre s otáznikom alebo named bindingy.

2. XSS — cross-site scripting

XSS nastáva keď aplikácia vloží nedôveryhodný obsah do HTML bez escapovania. Útočník môže ukradnúť session cookie, presmerovať používateľa alebo vykonať akcie jeho menom.

<?php
// CHYBA — priamy echo user inputu do HTML
echo "<div>" . $_POST['comment'] . "</div>";

// SPRÁVNE — htmlspecialchars pre HTML kontext
echo "<div>" . htmlspecialchars($_POST['comment'], ENT_QUOTES | ENT_HTML5, 'UTF-8') . "</div>";

// V Blade šablónach — {{ }} automaticky escapuje, {!! !!} neescape!
{{ $user->name }}       {{-- BEZPEČNÉ --}}
{!! $user->bio !!}       {{-- NEBEZPEČNÉ ak ide o user input --}}
# Content Security Policy hlavička — druhá vrstva ochrany
Content-Security-Policy: default-src 'self';
    script-src 'self' 'nonce-{RANDOM_NONCE}';
    style-src 'self' 'unsafe-inline';
    img-src 'self' data: https:;
    object-src 'none';

3. CSRF — cross-site request forgery

Laravel má CSRF ochranu zabudovanú — middleware VerifyCsrfToken automaticky overuje token pre všetky POST/PUT/DELETE requesty.

<!-- Blade formulár — automaticky pridáva CSRF token -->
<form method="POST" action="/orders">
    @csrf
    <!-- Polia formulára -->
</form>
// AJAX requesty — posielanie CSRF tokenu v hlavičke
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

fetch('/api/orders', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': csrfToken,
    },
    body: JSON.stringify(orderData),
});
// Výnimky z CSRF ochrany (napr. pre webhooky)
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    'webhooks/*',
    'stripe/webhook',
];

4. Bezpečné nahrávanie súborov

Nahrávanie súborov bez validácie je jedna z najčastejších bezpečnostných chýb. Útočník môže nahrať PHP súbor a spustiť ho na serveri.

// NIKDY nedôverujte MIME type z $_FILES — dá sa sfalšovať
$mimeType = $request->file('avatar')->getMimeType(); // NEDOSTATOČNÉ

// SPRÁVNE — overenie skutočného obsahu súboru
use Illuminate\Validation\Rules\File;

$request->validate([
    'avatar' => [
        'required',
        File::image()
            ->max(2 * 1024)    // max 2 MB
            ->dimensions(Rule::dimensions()->maxWidth(2000)->maxHeight(2000)),
    ],
    'document' => [
        File::types(['pdf', 'docx'])
            ->max(10 * 1024),
    ],
]);

// Ukladanie MIMO webroot alebo s náhodným názvom
$path = $request->file('avatar')->storeAs(
    'avatars',
    Str::uuid() . '.' . $request->file('avatar')->extension(),
    'private'  // 'private' disk = mimo public prístupu
);
Poskytujte súbory cez controller, nie priamo: Ak ukladáte súbory mimo webrootu (disk private), servírujte ich cez route s autentifikáciou a autorizáciou. Útočník nemôže priamo pristúpiť k URL súboru.

5. Secrets management — .env a konfigurácia

# NIKDY necommitujte .env do repozitára
# .gitignore
.env
.env.*.local
*.key
storage/oauth-*.key
# Kontrola či .env nie je v repozitári
git log --all --full-history -- .env
git ls-files .env

# Ak bol .env commitnutý — rotujte VŠETKY secret keys!
php artisan key:generate
# Zmeňte DB heslo, API kľúče, OAuth secrets
# Produkčné prostredie — environment variables zo systému (nie .env súbor)
# Napr. systemd service file
[Service]
Environment="APP_KEY=base64:..."
Environment="DB_PASSWORD=..."

# Alebo cez HashiCorp Vault / AWS Secrets Manager

6. Rate limiting — ochrana pred brute force a DoS

// Laravel route rate limiting
// routes/api.php
Route::middleware(['auth:sanctum', 'throttle:60,1'])->group(function () {
    Route::get('/user', [UserController::class, 'profile']);
});

// Vlastný rate limiter pre login
// app/Providers/AppServiceProvider.php
RateLimiter::for('login', function (Request $request) {
    return [
        Limit::perMinute(5)->by($request->email),           // 5 pokusov/min na e-mail
        Limit::perMinute(20)->by($request->ip()),            // 20 pokusov/min na IP
    ];
});
# Nginx rate limiting (pred PHP)
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location /login {
    limit_req zone=login burst=3 nodelay;
    try_files $uri /index.php?$query_string;
}

7. HTTP security hlavičky

# Nginx konfigurácia — kompletné security hlavičky
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; frame-src 'none'" always;
// Testovanie hlavičiek — online nástroj
// https://securityheaders.com — cieľ: hodnotenie A+

// PHP middleware pre Laravel
// Pridať do app/Http/Kernel.php ako globálny middleware
class SecurityHeaders
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);
        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'SAMEORIGIN');
        $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
        return $response;
    }
}

8. Autentifikácia a správa sessions

// Bezpečné hashovanie hesiel — bcrypt je default v Laraveli
$hashed = Hash::make($request->password);   // bcrypt, cost 12 predvolený
Hash::check($request->password, $user->password);

// Argon2id — bezpečnejšia alternatíva (PHP 7.3+)
$hashed = Hash::driver('argon2id')->make($request->password);
// Session konfigurácia pre produkciu
// config/session.php
'secure'    => env('SESSION_SECURE_COOKIE', true),  // HTTPS only
'http_only' => true,                                  // Neprístupné pre JS
'same_site' => 'lax',                                 // CSRF ochrana
'lifetime'  => 120,                                   // 2 hodiny

// Regenerácia session ID po prihlásení (Session Fixation ochrana)
// Laravel to robí automaticky cez Auth::login() a Auth::attempt()
// Dvojfaktorová autentifikácia — Laravel Fortify
composer require laravel/fortify
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

// config/fortify.php
'features' => [
    Features::twoFactorAuthentication([
        'confirm' => true,
        'confirmPassword' => true,
    ]),
],

9. Závislosť audit — composer a npm

# Kontrola bezpečnostných zraniteľností v PHP závislostiach
composer audit

# Automatická kontrola v CI/CD (GitHub Actions)
- name: PHP security audit
  run: composer audit --format=json --locked

# Pre Node.js závislosté
npm audit
npm audit fix
# Automatické security updates — GitHub Dependabot
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "composer"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

10. OWASP Top 10 — kompletný prehľad 2026

OWASP (Open Web Application Security Project) je medzinárodná nezisková organizácia, ktorá každé 3–4 roky vydáva zoznam 10 najkritickejších bezpečnostných rizík webových aplikácií. Tento zoznam — OWASP Top 10 — je priemyselný štandard: odvolávajú sa naň bezpečnostné audity, penetračné testy aj väčšina firemných bezpečnostných politík.

OWASP Top 10PHP ochranaLaravel built-in
A01 – Broken Access ControlGates, Policies, middlewareÁno (Policies)
A02 – Cryptographic FailuresOpenSSL, bcrypt/Argon2idÁno (Hash, Crypt)
A03 – Injection (SQL, XSS)Prepared statements, htmlspecialcharsÁno (Eloquent, Blade)
A04 – Insecure DesignThreat modeling, security by designManuálne
A05 – Security MisconfigurationAPP_DEBUG=false, security headersČiastočne
A06 – Vulnerable Componentscomposer audit, DependabotManuálne
A07 – Auth & Session FailuresBcrypt, secure cookies, 2FAÁno (Fortify)
A08 – Software Data Integritycomposer.lock, signed commitsČiastočne
A09 – Security LoggingLaravel Log, MonologÁno (Log facade)
A10 – SSRFWhitelisting URL, firewall pravidláManuálne

Záverečný bezpečnostný checklist

SQL injection: Všetky databázové queries používajú prepared statements alebo ORM
XSS: Všetky user inputs sú escapované pred výstupom; CSP hlavička je aktívna
CSRF: CSRF tokeny na všetkých formulároch; SameSite=Lax cookie
Upload: Validácia MIME type, max veľkosť, ukladanie mimo webroot
Secrets: .env v .gitignore; produkčné secrets v environment variables
Rate limiting: Login, registrácia a API endpointy majú limity
Security headers: HSTS, CSP, X-Frame-Options, X-Content-Type-Options aktívne
Heslá: bcrypt alebo Argon2id; nikdy MD5 ani SHA1
2FA: Dvojfaktorová autentifikácia dostupná pre používateľov (odporúčaná)
APP_DEBUG: V produkcii nastavené na false; chybové hlášky neodhaľujú stack trace
composer audit: Spustený v CI/CD pipeline; žiadne known vulnerabilities
HTTPS: HSTS povolený; HTTP presmerovaný na HTTPS; certifikát automaticky obnovovaný (Let's Encrypt)

Záver: bezpečnosť je proces, nie jednorazový audit

Žiadny checklist nezachytí všetky možné zraniteľnosti — ale pokrytie OWASP Top 10 a pravidelný composer audit eliminuje drvivú väčšinu skutočných útokov. Najdôležitejšie je integrovať bezpečnostné kontroly do CI/CD pipeline, nie ich riešiť manuálne tesne pred spustením projektu.

Pre kritické aplikácie (fintech, zdravotníctvo, e-commerce s citlivými dátami) odporúčam externý penetračný test aspoň raz ročne — automatické nástroje nenájdu logické zraniteľnosti v business logike.

Potrebujete bezpečnostný audit vašej PHP aplikácie?

Vykonám kódový audit, skontrolujeme OWASP Top 10 a zavedieme automatické bezpečnostné kontroly do vášho CI/CD. Odpoveď do 24 hodín.

Nezáväzný dopyt

Ďalšie články

Zavolať E-mail Dopyt

Ochrana súkromia

Táto stránka využíva cookies pre nevyhnutné fungovanie. Rešpektujeme vaše súkromie a legislatívu GDPR.