Blog OWASP Top 10 Checklist

Security PHP OWASP

An OWASP Top 10 Checklist for PHP Developers

A practical, no-fluff checklist for catching the most common security issues in PHP web applications — based on real code review findings.

Most PHP security problems aren't exotic. They're the same handful of issues showing up in codebases over and over again. The OWASP Top 10 is a good framework for thinking about them systematically. Here's how each one translates to concrete PHP code.

1. Injection — SQL, Command, LDAP

The classic. Never concatenate user input directly into a query.

bad.php
// NEVER do this
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = " . $_GET['id']);
good.php
// Use prepared statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);

Checklist: Every database query uses prepared statements or a query builder. No raw $_GET, $_POST, or $_COOKIE values concatenated into SQL strings.

2. Broken Authentication

Weak session handling is where most PHP apps fall down. Key things to check:

  • Call session_regenerate_id(true) on login
  • Use password_hash() and password_verify() — never MD5 or SHA1
  • Set session cookies with HttpOnly and Secure flags
  • Enforce a session timeout and destroy sessions on logout
session-config.php
// Harden session cookies
session_set_cookie_params([
    'lifetime' => 0,
    'path'     => '/',
    'secure'   => true,      // HTTPS only
    'httponly' => true,      // No JS access
    'samesite' => 'Strict',  // CSRF mitigation
]);
session_start();
session_regenerate_id(true);

3. Cross-Site Scripting (XSS)

Any time you output user-supplied data in HTML, escape it. Every time. No exceptions.

output.php
// Bad — outputs raw user input
echo $_GET['name'];

// Good — escape for HTML context
echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');

// Convenience wrapper
function e(string $s): string {
    return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}
echo e($_GET['name']);

Note: strip_tags() is not a substitute for htmlspecialchars(). It removes tags but doesn't neutralize attributes like onerror or onclick on allowed tags.

4. Insecure File Uploads

File uploads are one of the highest-risk features in any PHP application. The checklist here is longer:

  • Validate MIME type server-side using finfo, not $_FILES['type'] (that's user-controlled)
  • Enforce an allowlist of file extensions — deny everything not on it
  • Store uploads outside the document root, or in a directory with PHP execution disabled
  • Rename uploaded files to a random name — never use the original filename
  • Scan with ClamAV for malware before storing
  • Set a maximum file size both in PHP config and application logic

This is a living checklist — I'll keep adding to it. If you want a proper security review of your PHP application, get in touch.


← Back to blog Need a security review?