🐛#FixBugFixBug #12: SQL Injection để lại lỗ hổng bảo mật nghiêm trọng trên API đăng nhập
Tìm thấy lỗ hổng SQL injection trên endpoint /api/login do thiếu parameterized query. Hacker khai thác gây tràn bộ nhớ, xoá 23.000 bản ghi users. Bài học: luôn sanitize input.

Cuong Hoang
20 tháng 7, 2026 · 4 phút đọc · 24 lượt xem
const query = `SELECT * FROM users WHERE username = '${username}'`;
const result = await db.query(query);const result = await db.query(
'SELECT * FROM users WHERE username = $1',
[username]
);Triệu chứng
Đêm 15/03/2024, hệ thống监控 gửi cảnh báo: database CPU tăng đột biến 98%, memory consumption vượt ngưỡng. Kiểm tra log thấy hàng loạt query không có điều kiện WHERE, kèm payload lạ trong user input.
SELECT * FROM users WHERE username = 'admin' OR '1'='1'--'
Client báo lỗi 500 Internal Server Error khi truy cập /api/users, trong khi bảng logs ghi nhận ~15.000 request/giây từ cùng một IP.
Nguyên nhân gốc
- Query concatenation thay vì parameterized query - Developer sử dụng string interpolation để build SQL query:
// ĐOẠN CODE LỖI
const query = `SELECT * FROM users WHERE username = '${username}'`;
Không có rate limiting - Không giới hạn số request từ một IP, cho phép attacker gửi mass requests.
Database user có quyền DELETE - App user có quá nhiều privilege, dẫn đến khi injection thành công, attacker có thể DROP TABLE.
Cách sửa
Tức thời:
- Kill các connection đang chạy query độc hại
- Restore database từ backup gần nhất (4 giờ trước)
- Block IP tấn công tại firewall
Dài hạn:
- Rewrite toàn bộ query sử dụng parameterized queries hoặc ORM
- Thêm rate limiting middleware (100 req/phút/IP)
- Áp dụng nguyên tắc least privilege cho database user
- Thêm WAF (Web Application Firewall)
Bài học
String concatenation trong SQL là một trong những lỗi cổ điển nhất nhưng vẫn xảy ra. Dùng ORM hoặc prepared statements không chỉ bảo mật mà còn giúp maintainability tốt hơn. Backup và monitoring không thể thiếu - chúng ta mất 4 tiếng dữ liệu nhưng may mắn có backup để restore.
Bình luận