Thứ Tư, 17 tháng 6, 2026

SQL Injection là gì? (Khi hacker biến ô đăng nhập thành cửa sau vào nhà bạn)

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 mới làm website đầu tiên.

Có form login.

Nhìn rất chuyên nghiệp.


Username

Password

[ Login ]


Bạn "rung đùi" tự tin 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


Lính mới sẽ nghĩ:

"Chuyện quái gì đang xảy ra vậy? 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ụ thực tế 

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ý. Duyệt!"


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

Lính mới...ngơ ngác:

"Em chỉ muốn xóa user số 5 thôi mà..."



Một sự thật thú vị 

Ngày xửa, 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 lính 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

Lính mới thường test theo cách rất đơn giản:

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.


Tập tành làm web 

Trong giai đoạn đầu khi còn đang "vọc" những thứ miễn phí để "nâng cao tay nghề". Rất có thể bạn nghĩ: Host miễn phí nên bị hack.


Không đâu, "làm ơn" đừng nghĩ vậy.


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 "xịn sò"

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.