Lessons from real hacks every PHP developer should learn before it's too late
PHP runs most of the internet — and that makes it one of the most attacked ecosystems on earth.
Not because PHP is weak. But because insecure PHP applications are easy money for attackers.
The scary part?
Most PHP breaches follow the same handful of mistakes, repeated again and again by developers who didn't think their app was a target.
This article breaks down the most important security practices every PHP developer must follow, backed by real breach examples showing what happens when they're ignored.
1. Never Trust User Input
Breach Example: TalkTalk (2015)
The TalkTalk breach exposed personal data of over 150,000 customers.
The root cause? A basic SQL injection vulnerability caused by unvalidated user input.
Attackers didn't use advanced exploits. They injected malicious SQL through a form field that developers assumed was "safe."
What to do
Validate input early and aggressively.
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false) {
exit('Invalid request');
}Lesson: If input touches your app, assume it's hostile.
2. Escape Output to Prevent XSS
Breach Example: MySpace Samy Worm (2005)
One of the most famous XSS attacks ever.
A single JavaScript payload embedded in a user profile infected over 1 million users in hours.
Why? User content was rendered without escaping.
Safe output
echo htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');Lesson: XSS doesn't steal servers — it steals users.
3. Always Use Prepared Statements
Breach Example: Heartland Payment Systems (2008)
One of the largest data breaches in history — 130 million credit cards compromised.
It started with: SQL injection through poorly constructed queries.
Correct approach
$stmt = $pdo->prepare(
"SELECT * FROM users WHERE email = :email"
);
$stmt->execute(['email' => $email]);Lesson: SQL injection isn't clever. It's just effective.
4. Hash Passwords Properly
Breach Example: LinkedIn (2012)
LinkedIn lost 117 million passwords.
The issue? Passwords hashed with SHA-1, no salting, no stretching.
PHP gives you better tools — use them.
$passwordHash = password_hash($password, PASSWORD_DEFAULT);Lesson: If passwords leak, bad hashing turns a breach into a catastrophe.
5. Secure Sessions or Lose Accounts
Breach Example: Firesheep (2010)
Firesheep made session hijacking trivial on public Wi-Fi.
Attackers didn't steal passwords — they stole session cookies.
Secure cookies
session_set_cookie_params([
'secure' => true,
'httponly' => true,
'samesite' => 'Strict',
]);Lesson: Authentication doesn't matter if sessions are exposed.
6. Protect Against CSRF
Breach Example: Gmail CSRF Attacks (2008)
Attackers tricked logged-in users into triggering actions without consent.
No password theft. No malware. Just trust abuse.
CSRF token check
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'])) {
exit('Invalid request');
}Lesson: CSRF turns users into unwitting attackers.
7. Treat File Uploads as Weapons
Breach Example: WordPress Plugin Exploits
Countless WordPress breaches stem from insecure file uploads:
- Web shells
- Backdoors
- Ransomware
Attackers upload files pretending to be images — servers execute them.
Safer handling
- Rename files
- Validate MIME types
- Store outside web root
Lesson: If users can upload files, attackers will upload code.
8. Hide Error Messages in Production
Breach Example: Sony Pictures (2014)
Verbose error messages exposed:
- File paths
- Server structure
- Internal logic
Attackers used this info to move laterally.
Production config
display_errors = Off
log_errors = OnLesson: Error messages are reconnaissance tools.
9. Never Commit Secrets
Breach Example: Uber (2016)
Uber's AWS credentials were committed to GitHub.
Result? Attackers accessed 57 million user records.
Use environment variables
$dbPassword = $_ENV['DB_PASSWORD'];Lesson: Source code lives forever. Secrets should not.
10. Keep Dependencies Updated
Breach Example: Equifax (2017)
Equifax lost 147 million records due to an unpatched dependency.
Not custom code. Not a genius exploit.
Just an ignored update.
composer auditLesson: Outdated software is low-hanging fruit.
11. Authorization Bugs Leak Data
Breach Example: Facebook View As Bug (2018)
A flawed authorization check allowed attackers to steal 50 million access tokens.
Users were authenticated — but permissions were broken.
if ($resource->user_id !== $currentUser->id) {
http_response_code(403);
exit;
}Lesson: Authentication asks who you are. Authorization asks what you're allowed to do.
12. HTTPS Is Mandatory
Breach Example: Session Sniffing on Public Wi-Fi
Before HTTPS everywhere, attackers routinely stole:
- Cookies
- Sessions
- Credentials
HTTPS is no longer optional — it's the minimum bar.
Lesson: If traffic isn't encrypted, it isn't private.
Final Thoughts: Most Breaches Are Embarrassingly Simple
None of these breaches required:
- Zero-days
- Nation-state attackers
- Advanced malware
They required:
- Trusting input
- Skipping validation
- Ignoring updates
- Assuming "it won't happen"
Related Articles
If you enjoyed this one, these earlier articles, you may also like these articles.
- PHP Features That Deliver Real Value
- 10 More Under-the-Radar PHP Packages That Will Supercharge Your Projects
- 10 Under-the-Radar PHP Packages That Will Supercharge Your Projects'
- Underrated PHP Features That Every Software Engineer Will Love
- How to Learn Design Patterns (and Actually Use Them Like a Pro)
- When PHP 8.5 Met Domain-Driven Design: A Software Engineer's Quiet Revelation
- How PHP 8 Support Domain-Driven Design (DDD)
- Think Like an Architect: UML Diagrams Every Developer Should Master
About the Author
Mathews Jose is a Software Engineer with over a decade of experience specializing in PHP, REST APIs, and event-driven architectures. He's passionate about building scalable backend systems and exploring how emerging technologies like AI can seamlessly integrate into modern software architecture.
Connect with Mathews on LinkedIn