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
| Threat | Solution |
|---|---|
| SQL Injection | Prepared Statements |
| XSS | htmlspecialchars() |
| CSRF | Token validation |
| Password Leak | password_hash() |
| Dirty Input | filter_var() |






