DEV Community

Cover image for Building Secure APIs in PHP: Avoiding Common Vulnerabilities
Patoliya Infotech
Patoliya Infotech

Posted on

Building Secure APIs in PHP: Avoiding Common Vulnerabilities

Since APIs are essential to modern net and cellular packages, protecting them is more important than ever. It is important that we, as builders, implement modern security procedures to keep our data and users safe as PHP continues to power innumerable backends and RESTful APIs throughout the internet.

With real-world examples and workable solutions, we'll walk you through the most frequent vulnerabilities that impact PHP APIs in this post. After that, you'll have the best practices, resources, and extra advice you need to build reliable APIs with confidence.

🚨 Common Vulnerabilities in PHP APIs (with Examples & Fixes)

1. SQL Injection

The Problem: An attacker may be able to run arbitrary SQL commands if they enter unclean input directly into SQL queries.

// ❌ Vulnerable Code
$userId = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $userId";
$result = mysqli_query($conn, $query);
Enter fullscreen mode Exit fullscreen mode

What can go wrong?
Passing ?id=1 OR 1=1 would return all users.

βœ… Secure Fix (Using PDO with Prepared Statements):

// βœ… Safe Code

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
$user = $stmt->fetch();
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰** Use PDO with prepared statements always** β€” since it treats input as data rather than code, neutralizing injection vectors.

2. Authentication Flaws

The Problem: APIs are left insecure by inadequate password storage, nonexistent authentication levels, or unsafe token processing.

Weak Example:

// ❌ Storing raw password (never do this!)
$password = $_POST['password'];
file_put_contents('users.txt', $password);
Enter fullscreen mode Exit fullscreen mode

*βœ… Secure Password Hashing with bcrypt:
*

$hashedPassword = password_hash($_POST['password'], PASSWORD_BCRYPT);
// Store $hashedPassword in DB
Enter fullscreen mode Exit fullscreen mode

Use JWTs (JSON Web Tokens) for stateless authentication:

// Generating a JWT
use Firebase\JWT\JWT;

$payload = ['sub' => $userId, 'iat' => time()];
$jwt = JWT::encode($payload, $secretKey, 'HS256');
Enter fullscreen mode Exit fullscreen mode

πŸ” Don’t forget to verify JWTs on every request and set a reasonable expiration time.

Still deciding between Python and PHP? Read our guide to pick the right language for your project!

3. Cross-Site Scripting (XSS) in JSON Responses

The Problem: Even though JSON is thought to be XSS-proof, malevolent methods can nonetheless deliver dangerous output.

Example:

$data = ['name' => "<script>alert('xss');</script>"];
echo json_encode($data);
Enter fullscreen mode Exit fullscreen mode

βœ… Secure Fix:

  • Always validate and sanitize outputs.
  • Encode special characters before including in output, especially if embedding into HTML.
$data['name'] = htmlspecialchars($data['name'], ENT_QUOTES, 'UTF-8');
echo json_encode($data);
Enter fullscreen mode Exit fullscreen mode

Also consider setting Content-Type: application/json header to help browsers interpret responses correctly.

4. CSRF (Cross-Site Request Forgery)

The Problem: Even REST APIs are susceptible, particularly if they use cookies for authentication.

Fix:

  • Require a token (like a CSRF token or JWT) in headers.
  • Only accept state-changing requests (POST, PUT, DELETE) with proper Authorization headers.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
    if ($token !== $_SESSION['csrf_token']) {
        http_response_code(403);
        exit('Invalid CSRF token');
    }
}
Enter fullscreen mode Exit fullscreen mode

Curious why PHP remains a go-to for e-commerce in 2025? Discover how it powers modern online stores and why it could be the perfect choice for your business!

5. Sensitive Data Exposure

The Problem: Excessive sharing in API answers or lengthy error messages might provide attackers important information.

// ❌ Bad practice: returning raw DB errors
mysqli_query($conn, $badQuery) or die(mysqli_error($conn));

// ❌ Response with sensitive fields
echo json_encode($user); // Might include 'password', 'ssn', etc.
Enter fullscreen mode Exit fullscreen mode

βœ… Fixes:

  • Disable error display in production.
  • Whitelist only needed fields in responses.
// βœ… Only return safe fields
$response = [
    'id' => $user['id'],
    'name' => $user['name'],
];
Enter fullscreen mode Exit fullscreen mode

πŸ›‘ Best Practices for Securing PHP APIs

βœ… Use HTTPS always. Plain HTTP exposes tokens and data in transit.
βœ… Implement rate limiting & throttling. Prevent brute-force attacks and abuse (e.g., with middleware or reverse proxies like NGINX).
βœ… Validate all inputs. Use filter_var() and strict type checking.

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
Enter fullscreen mode Exit fullscreen mode

βœ… Encode all outputs. Use htmlspecialchars() and JSON encoding properly.

βœ… Handle errors gracefully.

if (!$user) {
    http_response_code(404);
    echo json_encode(['error' => 'User not found']);
}

Enter fullscreen mode Exit fullscreen mode

βœ… Set secure headers.

header("Content-Security-Policy: default-src 'none'");
header("X-Content-Type-Options: nosniff");
header("Access-Control-Allow-Origin: https://yourfrontend.com");
Enter fullscreen mode Exit fullscreen mode

For more, check the OWASP PHP Security Cheat Sheet.

πŸ’‘ Bonus Tips
πŸ“ Logging & Monitoring: Track failed logins, suspicious IPs, and unexpected payloads.

πŸ›  Use frameworks like Laravel or Symfony.

  • Laravel provides CSRF protection, rate limiting, secure auth scaffolding, and validation out-of-the-box.

πŸ” Scan your codebases.

  • Tools like PHPStan, Psalm, and SonarQube help detect vulnerabilities early.

βœ… Final Thoughts

Security is a continuous process and an attitude, not a one-time event. Since PHP still powers APIs in many different businesses, it is our responsibility to develop them properly and securely.

Key Takeaways:

  • Clean and verify everything, including tokens, output, and input.
  • Clients should never be trusted.
  • By default, make use of contemporary frameworks and technologies that keep you safe.

πŸ” Keep learning. Your understanding and code should also develop with security risks.

πŸ’¬ Let’s hear from you!
Do you have any tools, tricks, or advice for protecting your PHP APIs? Let's learn from each other, so leave them in the comments!

πŸ›‘οΈ Stay secure and keep coding! πŸ‘¨β€πŸ’»πŸ”₯

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.