SQL Injection là gì? Tại sao nên sử dụng PreparedStatament trong JAVA?

Hello các bạn, hôm nay mình xin giới thiệu về một lỗi bảo mật khá nghiêm trọng được gây ra bởi lập trình viên trong quá trình xử lý code mà hầu hết các website trong khoảng đầu năm 2000 đều tồn đọng. Lỗi này đặc biệt dễ được khai thác chỉ bởi những người dùng có kiến thức cơ bản về DBMS, đó là SQL Injection. Vậy SQL Injection là gì và cách phòng chống chúng trong ngôn ngữ lập trình nói chung và ngôn ngữ Java nói riêng?

  1.  SQL Injection?

SQL injection là một kỹ thuật cho phép những kẻ tấn công lợi dụng lỗ hổng của việc kiểm tra dữ liệu đầu vào trong các ứng dụng web và các thông báo lỗi của hệ quản trị cơ sở dữ liệu trả về để inject (tiêm vào) và thi hành các câu lệnh SQL bất hợp pháp. SQL injection có thể cho phép những kẻ tấn công thực hiện các thao tác, delete, insert, update, v.v. trên cơ sở dữ liệu của ứng dụng, thậm chí là server mà ứng dụng đó đang chạy. SQL injection thường được biết đến như là một vật trung gian tấn công trên các ứng dụng web có dữ liệu được quản lý bằng các hệ quản trị cơ sở dữ liệu như SQL Server, MySQL, Oracle, DB2, Sysbase…

– Dòng mã sau sẽ minh họa lỗi này:

statement

=

"SELECT * FROM users WHERE name = '"

+

userName

+

"';"

– Câu lệnh này được thiết kế để trả về các bản ghi tên người dùng cụ thể từ bảng những người dùng. Tuy nhiên, nếu biến “userName” được nhập chính xác theo một cách nào đó bởi người dùng ác ý, nó có thể trở thành một câu truy vấn SQL với mục đích khác hẳn so với mong muốn của tác giả đoạn mã trên. Ví dụ, ta nhập vào giá trị của biến userName như sau:

a' or 't'='t

– Khiến câu truy vấn có thể được hiểu như sau:

SELECT

*

FROM

users

WHERE

name

=

'a'

or

't'

=

't'

;

– Câu lệnh này là luôn đúng, bạn có thể đăng nhập vào hệ thống mà không cần sử dụng username và password. Nguy hiểm hơn nữa nếu tin tặc biết được cấu trúc của DBMS và chèn thêm đoạn mã sau:

SELECT

*

FROM

users

WHERE

name

=

'a'

or

't'

=

't'

;DROP TABLE users;

– Các ví dụ đủ để thấy được SQL injection là rất nguy hiểm, để tránh chúng, trong JAVA người ta sử dụng đến đối tượng PreparedStatement thay vì chỉ sử dụng các SQL Engine để truy vấn dữ liệu.

2. PreparedStatment

PreparedStatement  là một interface con của Statement. Nó được sử dụng để thực thi các truy vấn được tham số hóa. Bạn theo dõi ví dụ sau:

String sql="

INSERT

INTO

ten_bang

values

(?,?,?)

";

– Như bạn thấy, chúng ta đang truyền các tham số cho values. Giá trị của nó sẽ được thiết lập bằng việc gọi phương thức setter (ví dụ như setShort, setString, …) của PreparedStatement.

– Đối tượng PreparedStatement là một đối tượng mà biểu diễn một lệnh SQL được biên dịch trước. Tức là, một lệnh SQL được biên dịch trước và được lưu trữ trong một đối tượng PreparedStatement. Đối tượng này sau đó có thể được sử dụng để thực thi có hiệu quả Statement này nhiều lần. Điều này cải thiện hiệu suất đáng kể hơn việc sử dụng Statement truyền thống.

– Các phương thức setter của PreparedStatement coi các giá trị truyền vào chỉ có thể là một value, nó sẽ loại bỏ hoàn toàn các ký tự lạ mà người dùng nhập vào trái phép. Do đó loại bỏ mối nguy hại của SQL Injection.

Advertisement

Share this:

Thích bài này:

Thích

Đang tải…