13. Security in PHP

Security is critical in web development. A single mistake can expose your database, users, and server.


🛑 1. SQL Injection Prevention

❌ Problem:

User input directly added to SQL query:

$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = '$username'";

👉 Attacker can input:

' OR 1=1 --

✅ Solution: Use Prepared Statements

Using PDO:

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);

Using MySQLi:

$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();

✔ Prevents SQL injection completely


⚠️ 2. XSS (Cross-Site Scripting) Protection

❌ Problem:

Displaying user input directly:

echo $_GET['name'];

👉 Attacker injects:

<script>alert('Hacked')</script>

✅ Solution: Escape Output

echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');

✔ Converts <script> → safe text
✔ Prevents JavaScript execution


🔁 3. CSRF Protection (Cross-Site Request Forgery)

❌ Problem:

User performs actions without verification


✅ Solution: Use CSRF Token

Step 1: Generate token

session_start();
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

Step 2: Add in form

<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">

Step 3: Validate

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("Invalid CSRF token");
}

✔ Ensures request is from real user


🔑 4. Password Hashing

❌ Never do this:

$password = md5($password);

✅ Correct Method:

$hash = password_hash($password, PASSWORD_DEFAULT);

Verify password:

if (password_verify($password, $hash)) {
echo "Login successful";
}

✔ Uses strong encryption (bcrypt/argon)
✔ Automatically handles salting


🧼 5. Data Sanitization

Purpose:

Clean user input before processing


Methods:

Trim spaces:

$name = trim($_POST['name']);

Remove unwanted characters:

$name = filter_var($name, FILTER_SANITIZE_STRING);

Validate email:

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);

🚀 Bonus: Best Practices

✔ Always validate input (server-side)
✔ Use HTTPS
✔ Disable error display in production

ini_set('display_errors', 0);

✔ Use secure session:

session_regenerate_id(true);

✔ Set proper headers:

header("X-XSS-Protection: 1; mode=block");
header("X-Frame-Options: SAMEORIGIN");

📌 Summary Table

ThreatSolution
SQL InjectionPrepared Statements
XSShtmlspecialchars()
CSRFToken validation
Password Leakpassword_hash()
Dirty Inputfilter_var()