Know the Attacks
Understanding how attacks work helps you prevent them.
SQL Injection
Bad:
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
// Input: 1; DROP TABLE users;--
Good:
$user = DB::table('users')->where('id', $id)->first();
// Or prepared statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
XSS (Cross-Site Scripting)
Bad:
<div><?= $userInput ?></div>
// Input: <script>stealCookies()</script>
Good:
<div><?= htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8') ?></div>
// Blade does this automatically: {{ $userInput }}
CSRF (Cross-Site Request Forgery)
Always include CSRF tokens in forms:
<form method="POST">
@csrf
<!-- form fields -->
</form>
Security Headers
// In middleware or server config
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Content-Security-Policy: default-src \'self\'');
Password Storage
// Hash on registration
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
// Verify on login
if (password_verify($inputPassword, $hashedPassword)) {
// Valid
}
Input Validation
$validated = $request->validate([
'email' => 'required|email|max:255',
'age' => 'required|integer|min:0|max:150',
'url' => 'required|url',
]);
Quick Checklist
- [ ] Use HTTPS everywhere
- [ ] Hash passwords (bcrypt/Argon2)
- [ ] Escape output (XSS)
- [ ] Use prepared statements (SQL injection)
- [ ] Include CSRF tokens
- [ ] Validate all input
- [ ] Set security headers
- [ ] Keep dependencies updated
