Users can act outside their permissions. Includes SSRF. Most prevalent risk.
<?php
// Vulnerable
if ($_GET['user_id'] == $currentUserId) { ... }
// Secure: enforce on every request
if (!$auth->hasPermission('view_user', $requestedUserId)) {
http_response_code(403);
exit('Access denied');
}
// SSRF mitigation
$allowedHosts = ['api.example.com'];
$host = parse_url($url, PHP_URL_HOST);
if (!in_array($host, $allowedHosts, true)) {
die('Invalid URL');
}
?>
Default configs, exposed debug, unnecessary features.
display_errors = Off, expose_php = Off in php.iniopen_basedir, disable allow_url_includedisable_functions = exec,system,shell_exec,passthru,proc_open<?php
// Production bootstrap
ini_set('display_errors', '0');
error_reporting(E_ALL); // but never display
?>
Compromised dependencies, malicious packages, outdated components.
composer audit and composer outdated regularlycomposer.lock + lock to exact versionsWeak algorithms, improper key management, sensitive data exposure.
<?php
// Secure password storage (never roll your own)
$hash = password_hash($password, PASSWORD_ARGON2ID);
// Verify
if (!password_verify($password, $storedHash)) { ... }
// Never use MD5/SHA1 for passwords
// Use sodium for symmetric encryption (libsodium is bundled)
$key = sodium_crypto_secretbox_keygen();
$encrypted = sodium_crypto_secretbox($data, $nonce, $key);
?>
SQLi, command injection, LDAP injection, etc. Still common in PHP.
<?php
// SQL Injection prevention
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $userId]);
// Command injection
$safeDir = escapeshellarg($userInput);
exec("ls $safeDir");
// Use filter_input + whitelist validation
?>
Flaws in architecture and threat modeling. Not fixable with code alone.
Weak credential handling, session fixation, credential stuffing.
<?php
session_start([
'cookie_httponly' => true,
'cookie_samesite' => 'Strict',
'cookie_secure' => true,
'use_strict_mode' => true
]);
// After login
session_regenerate_id(true);
// Rate-limit login attempts (use Redis or DB)
?>
Deserialization, unsigned updates, CI/CD tampering (below supply chain).
<?php
// Never use unserialize() on user input
// Prefer JSON + validation or signed JWTs
// Validate signed data
if (!hash_equals($expectedSignature, $providedSignature)) {
die('Integrity check failed');
}
?>
Insufficient logging of security events, no monitoring.
Information disclosure via stack traces, improper error handling.
<?php
// Global handler
set_exception_handler(function (Throwable $e) {
error_log($e->getMessage()); // never echo to user
http_response_code(500);
echo 'Internal server error';
});
// PDO exceptions
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>