Một cuộc thi "cún đẹp" dành riêng cho các bạn cún loài Chihuahua. Đặc điểm của loài Chihuahua là luôn sủa ăng ẳng, vì vậy ban tổ chức "cẩn thận" thông báo: Chỉ cho phép các cún Chihuahua và các cún luôn sủa ăng ẳng được vào cổng.
Một chú chó German Shepherd to lớn, không có "giấy mời" vẫn nghênh ngang vào cổng chỉ vì chú có một tật ít ai ngờ đó là sủa ăng ẳng suốt ngày! Chú là "khách không mời"! Và thông báo của Ban Tổ Chức có một "lỗ hổng". Quay lại với lập trình, bạn làm website đầu tiên.Có form login.
Nhìn rất chuyên nghiệp.
😎
Username
Password
[ Login ]
Bạn nghĩ:
"Chỉ có tôi biết tài khoản admin thôi."
Nhưng vài phút sau.
💀
Hacker đăng nhập được.
Trong khi:
Không biết password
Không biết admin là ai
Không hack server
Người mới:
"Ủa?"
"PHP phản chủ rồi à?"
😵
SQL Injection là gì?
SQL Injection là một lỗ hổng bảo mật xảy ra khi dữ liệu người dùng nhập vào được ghép trực tiếp vào câu lệnh SQL.
Kẻ tấn công có thể:
- Đăng nhập trái phép
- Xem dữ liệu
- Xóa dữ liệu
- Thậm chí chiếm quyền quản trị
Đây là một trong những lỗ hổng nổi tiếng nhất trong lịch sử web.
Ví dụ đời thường 🍜
Bạn tới một khu chung cư.
Bảo vệ hỏi:
"Anh ở căn hộ nào?"
Bạn trả lời:
"Tôi ở căn hộ 101."
😎
Bảo vệ kiểm tra.
Nếu đúng.
👉 Cho vào.
Nhưng có một người khác trả lời:
"Tôi ở căn hộ 101 hoặc bất kỳ căn hộ nào cũng được."
🤡
Và bảo vệ vẫn cho vào.
Đó chính là tinh thần của SQL Injection.
Ví dụ đau lòng 😭
Form Login:
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users
WHERE username='$username'
AND password='$password'";
Nhìn rất bình thường.
😎
Người dùng nhập:
admin
123456
PHP tạo:
SELECT * FROM users
WHERE username='admin'
AND password='123456'
Không có vấn đề gì.
Hacker nhập gì? 😱
Username:
admin
Password:
' OR '1'='1
Lúc này câu SQL trở thành:
SELECT * FROM users
WHERE username='admin'
AND password='' OR '1'='1'
Nhìn kỹ:
'1'='1'
luôn đúng.
😅
Database:
"Ờ cũng hợp lý."
🤡
Và hacker vào được.
💀
Vì sao chuyện này xảy ra?
Nguyên nhân nằm ở đây:
$sql = "SELECT ...
WHERE username='$username'";
Bạn đang cho phép người dùng:
Viết dữ liệu
↓
Chen vào SQL
Database không phân biệt được:
Đâu là dữ liệu
Đâu là câu lệnh
Đó chính là nguồn gốc của SQL Injection.
Một ví dụ cực kỳ nguy hiểm 😭
Code:
$id = $_GET['id'];
$sql = "DELETE FROM users
WHERE id=$id";
Người dùng bình thường:
?id=5
SQL:
DELETE FROM users
WHERE id=5
Ổn.
Nhưng hacker:
?id=5 OR 1=1
SQL:
DELETE FROM users
WHERE id=5 OR 1=1
Vì:
1=1
luôn đúng.
Kết quả:
💀
Xóa toàn bộ users
Người mới:
"Em chỉ muốn xóa user số 5 thôi mà..."
😭
Một sự thật thú vị 😎
Ngày xưa.
SQL Injection nguy hiểm tới mức:
- Website ngân hàng
- Website chính phủ
- Website thương mại điện tử
đều từng dính.
Nó từng là "ông vua" của các lỗ hổng web.
Sai lầm phổ biến của người mới 🤡
❌ Nghĩ rằng:
Website nhỏ
Không ai hack
Thực tế:
Bot tự động quét Internet 24/7.
Không cần nổi tiếng.
Không cần nhiều traffic.
Vẫn có thể bị thử SQL Injection.
❌ Chỉ kiểm tra giao diện
Người mới thường test:
admin
123456
Đăng nhập được.
😎
Và nghĩ:
Hoàn thành
Trong khi hacker lại nhập:
' OR '1'='1
😅
Dấu hiệu code dễ bị SQL Injection
Ví dụ:
$sql = "SELECT * FROM users
WHERE username='$username'";
Hoặc:
$sql = "SELECT * FROM products
WHERE id=".$_GET['id'];
Hoặc:
$sql = "DELETE FROM users
WHERE id=$id";
Nếu thấy:
Ghép chuỗi trực tiếp
thì nên cảnh giác.
InfinityFree Case 😅
Nhiều bạn nghĩ:
"Host miễn phí nên bị hack."
Không.
SQL Injection xảy ra ở:
Code
chứ không phải:
Hosting
Dù:
- InfinityFree
- Shared Hosting
- VPS
- Dedicated Server
thì code sai vẫn nguy hiểm như nhau.
Debug kiểu dev thật 😎
✅ 1. Echo câu SQL
Ví dụ:
echo $sql;
Xem dữ liệu người dùng đã chèn vào gì.
✅ 2. Test ký tự đặc biệt
Ví dụ:
'
"
--
;
Website có lỗi không?
✅ 3. Không ghép chuỗi trực tiếp
Đây là nguyên tắc quan trọng nhất.
Checklist chuẩn không cần chỉnh 😎
☑ Không ghép SQL bằng dữ liệu người dùng
☑ Kiểm tra mọi GET/POST
☑ Test ký tự '
☑ Test ký tự "
☑ Test URL
☑ Không chủ quan vì website nhỏ
☑ Hiểu Prepared Statement
FAQ nhanh
SQL Injection có còn tồn tại không?
→ Có.
Rất nhiều website nhỏ vẫn mắc.
Chỉ PHP mới bị SQL Injection?
→ Không.
Nhiều ngôn ngữ đều có thể gặp.
SQL Injection có phải do MySQL lỗi?
→ Không.
Thường do cách lập trình.
Website cá nhân có cần quan tâm không?
→ Có.
Đặc biệt nếu có:
- Login
- Form
- Database
Bạn có thể cũng đang gặp 😭
👉 MySQL INSERT không chạy
👉 Login đúng password nhưng vẫn fail
👉 Prepared Statement là gì?
👉 mysqli vs PDO – chọn cái nào?
👉 JOIN là gì?
👉 Backup database đúng cách
Tổng kết
SQL Injection xảy ra khi:
👉 Dữ liệu người dùng được ghép trực tiếp vào câu SQL.
Kết quả có thể từ:
Đăng nhập trái phép
cho tới:
Mất toàn bộ dữ liệu
💀
Điều đáng sợ nhất là:
Website vẫn chạy bình thường.
Không báo lỗi.
Không có warning.
Không có Fatal Error.
Nhưng cánh cửa sau đã mở sẵn cho hacker từ lâu. 😵