SQL Injection (SQLi) là một kiểu tấn công tiêm giúp nó có thể thực thi các câu lệnh SQL độc hại. Các câu lệnh này kiểm soát một máy chủ cơ sở dữ liệu đằng sau một ứng dụng web. Những kẻ tấn công có thể sử dụng lỗ hổng SQL Injection để vượt qua các biện pháp bảo mật ứng dụng. Họ có thể đi xung quanh xác thực và ủy quyền của một trang web hoặc ứng dụng web và truy xuất nội dung của toàn bộ cơ sở dữ liệu SQL. Họ cũng có thể sử dụng SQL Injection để thêm,sửa đổi và xóa các bản ghi trong cơ sở dữ liệu.

Lỗ hổng SQL Injection có thể ảnh hưởng đến bất kỳ trang web hoặc ứng dụng web nào sử dụng cơ sở dữ liệu SQL như MySQL, Oracle, SQL Server hoặc các trang web khác. Tội phạm có thể sử dụng nó để truy cập trái phép vào dữ liệu nhạy cảm của bạn: thông tin khách hàng, dữ liệu cá nhân, bí mật thương mại,sở hữu trí tuệ,v.v. Các cuộc tấn công SQL Injection là một trong những lỗ hổng ứng dụng web lâu đời nhất, phổ biến nhất và nguy hiểm nhất.


Làm thế nào và tại sao một cuộc tấn công SQL Injection được thực hiện

Để thực hiện một cuộc tấn công SQL Injection, kẻ tấn công trước tiên phải tìm thấy các đầu vào dễ bị tấn công của người dùng trong trang web hoặc ứng dụng web. Trang web hoặc ứng dụng web có lỗ hỏng SQL Injection sử dụng đầu vào của người dùng như vậy trực tiếp trong một truy vấn SQL. Kẻ tấn công có thể tạo nội dung đầu vào. Nội dung như vậy thường được gọi là tải trọng độc hại và là phần quan trọng của cuộc tấn công. Sau khi kẻ tấn công gửi nội dung này, các lệnh SQL độc hại sẽ được thực thi trong cơ sở dữ liệu.

SQL là một ngôn ngữ truy vấn được thiết kế để quản lý dữ liệu được lưu trữ trong cơ sở dữ liệu quan hệ. Bạn có thể sử dụng nó để truy cập, sửa đổi và xóa dữ liệu. Nhiều ứng dụng web và trang web lưu trữ tất cả dữ liệu trong cơ sở dữ liệu SQL. Trong một số trường hợp, bạn cũng có thể sử dụng các lệnh SQL để chạy các lệnh của hệ điều hành. Do đó, một cuộc tấn công SQL Injection thành công có thể gây ra những hậu quả rất nghiêm trọng.

- Những kẻ tấn công có thể sử dụng SQL Injection để tìm thông tin đăng nhập của những người dùng khác trong cơ sở dữ liệu. Sau đó, họ có thể mạo danh những người dùng này. Người dùng bị mạo danh có thể là quản trị viên cơ sở dữ liệu với tất cả các đặc quyền cơ sở dữ liệu.

- SQL cho phép bạn chọn và xuất dữ liệu từ cơ sở dữ liệu. Lỗ hổng SQL Injection có thể cho phép kẻ tấn công có quyền truy cập hoàn toàn vào tất cả dữ liệu trong máy chủ cơ sở dữ liệu.

- SQL cũng cho phép bạn thay đổi dữ liệu trong cơ sở dữ liệu và thêm dữ liệu mới. Ví dụ: trong một ứng dụng tài chính,kẻ tấn công có thể sử dụng SQL Injection để thay đổi số dư, làm mất hiệu lực giao dịch hoặc chuyển tiền vào tài khoản của chúng.

- Bạn có thể sử dụng SQL để xóa bản ghi khỏi cơ sở dữ liệu, thậm chí bỏ bảng. Ngay cả khi quản trị viên thực hiện sao lưu cơ sở dữ liệu, việc xóa dữ liệu có thể ảnh hưởng đến tính khả dụng của ứng dụng cho đến khi cơ sở dữ liệu được khôi phục. Ngoài ra, các bản sao lưu có thể không bao gồm dữ liệu gần đây nhất.

- Trong một số máy chủ cơ sở dữ liệu, bạn có thể truy cập hệ điều hành bằng máy chủ cơ sở dữ liệu. Điều này có thể là cố ý hoặc tình cờ. Trong trường hợp này,kẻ tấn công có thể sử dụng SQL Injection làm vector ban đầu và sau đó tấn công mạng nội bộ đằng sau tường lửa.

Có một số kiểu tấn công SQL Injection: in-band SQLi (sử dụng lỗi cơ sở dữ liệu hoặc lệnh UNION), blin SQLi và out-of-band SQLi.


Ví dụ về SQL Injection đơn giản

Ví dụ đầu tiên rất đơn giản. Nó cho thấy, làm thế nào kẻ tấn công có thể sử dụng lỗ hổng SQL Injection để đi xung quanh bảo mật ứng dụng và xác thực với tư cách là quản trị viên.

Tập lệnh sau là mã giải được thực thi trên máy chủ web. Đây là một ví dụ đơn giản về xác thực bằng username và password. Cơ sở dữ liệu ví dụ có một bảng được đặt tên users với các cột sau: username pasword.

SQL Injection (SQLi) là gì và cách ngăn chặn nó

Các trường đầu vào này dễ bị SQL Injection. Kẻ tấn công có thể sử dụng các lệnh SQL trong đầu vào theo cách có thể thay đổi câu lệnh SQL được thực thi bởi máy chủ cơ sở dữ liệu. Ví dụ: họ có thể sử dụng một thủ thuật liên quan đến một trích dẫn duy nhất và đặt trường passwd thành:

SQL Injection (SQLi) là gì và cách ngăn chặn nó

Kết quả là máy chủ cơ sở dữ liệu chạy truy vấn SQL sau:

SQL Injection (SQLi) là gì và cách ngăn chặn nó

Bởi vì câu lệnh OR 1=1, Where mệnh đề trả về đầu tiên id bảng users bất kể cái username password là gì. Người dùng đầu tiên id trong cơ sở dữ liệu thường là quản trị viên. Bằng cách này, kẻ tấn công không chỉ bỏ qua xác thực mà còn có được đặc quyền của quản trị viên. Họ cũng có thể nhận xét phần còn lại của câu lệnh SQL để kiểm soát thêm việc thực thi truy vấn SQL:

SQL Injection (SQLi) là gì và cách ngăn chặn nó


Ví dụ về SQL Injection dựa trên Union Based

Một trong những kiểu SQL Injection phổ biến nhất sử dụng toán tử UNION. Nó cho phép kẻ tấn công kết hợp kết quả của hai hoặc nhiều câu lệnh SELECT thành một kết quả duy nhất. Kỹ thuật này được gọi là SQL Injection dựa trên Union-based.

Sau đây là một ví dụ về kỹ thuật này. Nó sử dụng trang web testphp.vulnweb.com, một trang web có chủ đích dễ bị tấn công do Acunetix lưu trữ.

Yêu cầu HTTP sau là một yêu cầu bình thường mà người dùng hợp pháp sẽ gửi:

SQL Injection (SQLi) là gì và cách ngăn chặn nóSQL Injection (SQLi) là gì và cách ngăn chặn nó

Tham số artist dễ bị SQL Injection. Trọng tải sau sửa đổi truy vấn để tìm kiếm một bản ghi không tồn tại. Nó đặt giá trị trong chuỗi truy vấn URL thành -1. Tất nhiên, nó có thể là bất kỳ giá trị nào khác không tồn tại trong cơ sở dữ liệu. Tuy nhiên, một giá trị âm là một dự đoán tốt vì một số nhận dạng trong cơ sở dữ liệu hiếm khi là một số âm.

Trong SQL Injection, UNION toán tử thường được sử dụng để đính kèm một truy vấn SQL độc hại vào truy vấn ban đầu được ứng dụng web dự định chạy. Kết quả của truy vấn được đưa vào sẽ được nối với kết quả của truy vấn ban đầu. Điều này cho phép kẻ tấn công lấy các giá trị cột từ các bảng khác.

SQL Injection (SQLi) là gì và cách ngăn chặn nóSQL Injection (SQLi) là gì và cách ngăn chặn nó

Ví dụ sau đây cho thấy cách sử dụng trọng tải SQL Injection để lấy dữ liệu có ý nghĩa hơn từ trang web có cố ý dễ bị tấn công này.

SQL Injection (SQLi) là gì và cách ngăn chặn nó

SQL Injection (SQLi) là gì và cách ngăn chặn nó


Cách ngăn chặn SQL Injection

Cách chắn chắn duy nhất để ngăn chặn các cuộc tấn công SQL Injection là xác thực đầu vào và các truy vấn được tham số hóa bao gồm các câu lệnh đã chuẩn bị. Mã ứng dụng không bao giờ được sử dụng đầu vào trực tiếp. Nhà phát triển phải lọc tất cả dữ liệu đầu vào, chẳng hạn như trang web đăng nhập. Phải loại bỏ các phần tử mã độc tiềm ẩn chẳng hạn như các dấu ngoặc kép. Bạn cũng nên tắt khả năng hiển thị lỗi cơ sở dữ liệu trên các trang web sản xuất của mình. Lỗi cơ sở dữ liệu có thể được sử dụng với SQL Injection để lấy thông tin về cơ sở dữ liệu của bạn.

Việc ngăn chặn lỗ hổng SQL Injection không hề đơn giản. Các kỹ thuật phòng chống cụ thể phụ thuộc vào kiểu của lỗ hổng. Tuy nhiên, có một số nguyên tắc chiến lược chung nhất định mà bạn nên tuân theo để giữ an toàn cho ứng dụng web của mình:

1. Đào tạo và duy trì nhận thức:

Để giữ cho ứng dụng web của bạn an toàn, mọi người tham gia vào việc xây dựng ứng dụng web phải nhận thức được những rủi ro liên quan đến SQL Injection. Bạn nên cung cấp khóa đào tạo bảo mật phù hợp cho tất cả nhân viên.

2. Không thể tin tưởng bất kỳ dữ liệu đầu vào nào của người dùng

Coi tất cả dữ liệu đầu vào của người dùng là không đáng tin cậy. Bất kỳ dữ liệu nào của người dùng được sử dụng trong truy vấn SQL đều có nguy cơ xuất hiện SQL Injection.

3. Sử dụng danh sách trắng, không phải danh sách đen

Không lọc đầu vào của người dùng dựa trên danh sách đen. Một kẻ tấn công thông minh hầu như sẽ luôn tìm ra cách để vượt qua danh sách đen của bạn. Nếu có thể, hãy xác minh và lọc thông tin đầu vào của người dùng chỉ bằng cách sử dụng danh sách trắng nghiêm ngặt.

4. Áp dụng các công nghệ mới nhất

Các công nghệ phát triển web cũ hơn không có tính năng bảo vệ SQLi. Sử dụng phiên bản mới nhất của môi trường và ngôn ngữ phát triển và các công nghệ mới nhấ liên quan đến môi trường,ngôn ngữ đó. Ví dụ trong PHP sử dụng PDO thay vì MySQLi.

5. Sử dụng các cơ chế đã được xác minh

Đừng cố gắng xây dựng bảo vệ SQLi từ đầu. Hầu hết các công nghệ phát triển hiện đại có thể cung cấp cho bạn các cơ chế để bảo vệ chống lại SQLi. Sử dụng các cơ chế như vậy thay vì cố gắng phát minh lại bánh xe. Ví dụ: sử dụng các truy vấn được tham số hóa hoặc các thủ tục được lưu trữ.

6. Quét thường xuyên (với Acunetix)

SQL Injection có thể được giới thiệu bởi các nhà phát triển của bạn hoặc thông qua các thư viện/mô-đun/ phần mềm bên ngoài. Bạn nên thường xuyên các ứng dụng web của mình bằng trình quét lỗ hổng web như Acunetix. Nếu bạn sử dụng Jenkins, bạn nên cài đặt plugin Acunetix để tự động quét mọi bản dựng.


Các câu hỏi thường gặp

1. SQL Injection là gì?

SQL Injection là một lỗ hổng web gây ra bởi những sai lầm của lập trình viên. Nó cho phép kẻ tấn công gửi lệnh đến cơ sở dữ liệu mà trang web hoặc ứng dụng web giao tiếp. Điều này cho phép kẻ tấn công lấy dữ liệu từ cơ sở dữ liệu hoặc thậm chí sửa đổi nó.

2. SQL Injection phổ biến như thế nào?

SQL Injection là một lỗ hổng rất cũ – nó được phát hiện vào năm 1998. Tuy nhiên theo nghiên cứu năm 2020 của chúng tôi, 8% các trang web và ứng dụng web có lỗ hổng SQL Injection.

3. SQL Injection nguy hiểm như thế nào?

Một cuộc tấn công SQL Injection thành công có thể dẫn đến sự xâm phạm hoàn toàn hệ thống hoặc đánh cắp toàn bộ cơ sở dữ liệu. Ví dụ, một cuộc tấn công SQL Injection vào năm 2019 đã dẫn đến việc đánh cắp toàn bộ dữ liệu thuế của 5 triệu người.

4. Làm thế nào để phát hiện SQL Injection?

Cách hiệu quả để phát hiện SQL Injection là sử dụng máy quét lỗ hổng, thường được gọi là công cụ DAST. Acunetix được biết đến là công ty hàng đầu trong việc phát hiện SQL Injection và các lỗ hổng khác. Acunetix có thể đến được nơi mà các máy quét khác không thành công.

5. Làm thế nào để ngăn chặn SQL Injection?

Cách tốt nhất để ngăn chặn SQL Injection là sử dụng các hàm lập trình an toàn để làm cho SQL Injection không thể thực hiện được : các truy vấn được tham số hóa và các thủ tục được lưu trữ. Mọi ngôn ngữ lập trình chính hiện nay đều có các chức năng an toàn như vậy và mọi nhà phát triển chỉ nên sử dụng các chức năng an toàn như vậy để làm việc với cơ sở dữ liệu.