[2024] SQL Injection là gì? Phòng ngừa, ngăn chặn SQL Injection

SQL Injection là gì? Trong số tất cả các cuộc tấn công hướng vào trang web, tấn công SQL Injection được xem là một dạng rủi ro nguy hiểm và phổ biến nhất, gây ra tổn thất đáng kể cho nhiều doanh nghiệp và tổ chức trong thời gian qua. Vậy làm thế nào để phòng ngừa và ngăn chặn SQL Injection? Mời bạn cùng tìm hiểu qua bài viết sau đây của VinaHost.

1. SQL Injection là gì?

SQL Injection là một kỹ thuật chèn mã code, được sử dụng để tấn công các ứng dụng chứa dữ liệu (data-driven).

Trong quá trình này, các lệnh SQL có hại được chèn vào một trường nhập nội dung để thực thi (ví dụ như để trích xuất nội dung từ cơ sở dữ liệu cho hacker). Để thành công, SQL Injection phải tận dụng các lỗ hổng bảo mật trong phần mềm của ứng dụng.

SQL injection la gi
SQL Injection là một kỹ thuật chèn mã code, được sử dụng để tấn công các ứng dụng chứa dữ liệu (data-driven).

SQL Injection thường được biết đến như một phương thức tấn công chủ yếu đối với các trang web, tuy nhiên, nó cũng có thể được áp dụng để tấn công vào bất kỳ loại cơ sở dữ liệu SQL nào.

Các cuộc tấn công SQL Injection giúp hacker giả mạo danh tính, làm xáo trộn dữ liệu, làm mất hiệu lực giao dịch, thay đổi số dư, tiết lộ hoặc phá hủy dữ liệu trên hệ thống. Thậm chí, nó có thể khiến dữ liệu trở nên không khả dụng hoặc đạt được quyền quản trị của máy chủ cơ sở dữ liệu.

Xem thêm: [Tìm Hiểu] Trojan là gì? | Dấu hiệu & Ngăn chặn Virus Trojan

2. Các dạng tấn công SQL Injection

SQL Injection được chia thành ba loại: In-band SQLi (Classic), Inferential SQLi (Blind) và Out-of-band SQLi. Có thể phân loại các dạng SQL injection dựa trên cách tiếp cận để truy cập dữ liệu backend hoặc theo khả năng gây hại của chúng.

2.1. In-band SQLi

Hacker sử dụng cùng một kênh liên lạc để bắt đầu cuộc tấn công và thu thập các kết quả. Sự đơn giản và hiệu quả của In-band SQLi đã làm cho nó trở thành một trong những loại tấn công SQL phổ biến nhất hiện nay. Có hai biến thể phụ của phương pháp này:

  • Error-based SQLi: Kẻ tấn công thực hiện các hành động để tạo ra thông báo lỗi từ cơ sở dữ liệu. Dữ liệu từ các thông báo lỗi này sẽ được sử dụng để thu thập thông tin về cấu trúc của cơ sở dữ liệu.
  • Union-based SQLi: Phương pháp này tận dụng toán tử UNION SQL để kết hợp nhiều câu lệnh được tạo bởi cơ sở dữ liệu để nhận một phản hồi HTTP. Phản hồi này có thể chứa dữ liệu mà Hacker cần.

2.2. Inferential (Blind) SQLi

Hacker sẽ truyền các data payload tới máy chủ và theo dõi phản ứng cũng như hành vi của máy chủ để tìm hiểu về cấu trúc của nó. Phương pháp này được gọi là Blind SQLi vì dữ liệu không được chuyển trực tiếp từ cơ sở dữ liệu của trang web đến hacker. Do đó, hacker không thể xem thông tin về cuộc tấn công trong in-band.

Blind SQL injection dựa trên phản ứng và hành vi hoạt động của máy chủ. Vì vậy, chúng thường thực thi chậm hơn, nhưng có thể gây ảnh hưởng tương tự. Blind SQL injection có thể được phân loại thành:

  • Boolean: Kẻ tấn công gửi một truy vấn SQL đến cơ sở dữ liệu, khiến ứng dụng trả về một kết quả. Kết quả có thể thay đổi tùy thuộc vào truy vấn là đúng hay sai. Dựa vào kết quả này, thông tin trong HTTP response sẽ được điều chỉnh hoặc giữ nguyên. Sau đó, hacker có thể xác định xem thông điệp tạo ra kết quả có đúng hay không.
  • Time-based: Kẻ tấn công gửi một truy vấn SQL đến cơ sở dữ liệu, làm cho cơ sở dữ liệu chờ trong vài giây trước khi tiếp tục hoạt động. Sau đó, hacker có thể kiểm tra thời gian mà cơ sở dữ liệu cần để phản hồi, từ đó xác định xem một truy vấn là đúng hay sai. Dựa trên kết quả này, một HTTP response sẽ được tạo ra. Hacker có thể xác định thông điệp mà họ đã sử dụng có trả về đúng hay sai mà không cần dựa vào dữ liệu từ cơ sở dữ liệu.

2.3. Out-of-band SQLi

Hacker chỉ có thể triển khai hình thức này khi có một số tính năng cụ thể được kích hoạt trên máy chủ cơ sở dữ liệu mà ứng dụng web đang sử dụng. Hình thức này thường được sử dụng để thay thế cho các kỹ thuật khác như in-band và inferential SQLi.

Out-of-band SQLi được thực hiện khi hacker không thể sử dụng cùng một kênh để khởi động tấn công và thu thập thông tin, có thể do máy chủ quá chậm hoặc không ổn định để thực hiện hành động này. Các kỹ thuật này tận dụng khả năng của máy chủ tạo ra các yêu cầu DNS hoặc HTTP để chuyển dữ liệu cho kẻ tấn công.

Xem thêm: Tấn công Deface là gì? Cách phòng chống & khắc phục Deface

3. Cách tấn công website bằng SQL Injection

Cuộc tấn công SQL Injection được thực hiện bằng cách truyền lệnh SQL độc hại tới máy chủ cơ sở dữ liệu thông qua các yêu cầu từ phía người dùng. Bất kỳ kênh nhập liệu nào cũng có thể được sử dụng để truyền các lệnh độc hại, bao gồm cả thẻ `<input>`, chuỗi truy vấn (query strings), cookie và tệp tin.

Để hiểu cách nó thực hiện, hãy xét đến trường hợp bạn có một biểu mẫu đăng nhập với 2 trường là username và password như sau:

SQL injection la gi
Biểu mẫu đăng nhập với 2 trường là username và password

Khi người dùng nhập thông tin đăng nhập và nhấn nút “log in”, dữ liệu sẽ được gửi đến máy chủ web của bạn, nơi nó sẽ được kết hợp với một lệnh SQL. Ví dụ, trong PHP, đoạn code có thể như sau:

$sql_command=”select * from users where username = ‘”.$_POST[‘username’];

$sql_command.=”‘ AND password = ‘”.$_POST[‘password’].”‘”;

Sau đó, lệnh này sẽ được chuyển đến một máy chủ cơ sở dữ liệu, và tập dữ liệu kết quả sẽ xác định liệu username và password có phù hợp với tài khoản người dùng hợp lệ hay không. Ví dụ, nếu người dùng nhập “john” làm username và “123456” làm password, lệnh sẽ được chuyển đổi thành code như sau:

SELECT * FROM users WHERE username=’john’ AND password=’123456′

Tuy nhiên, nếu người dùng quyết định thử một cách khác, ví dụ như john’ OR 1=1; —

SQL injection la gi
Nếu người dùng quyết định thử một cách khác, ví dụ như john’ OR 1=1; —

Lệnh kết quả sẽ có dạng:

SELECT * FROM users WHERE username=’john’ OR 1=1; — ‘ AND password=’123456’

Kết quả trả về sẽ là thông tin đăng nhập của người dùng có tên là “john” mà không cần phải nhập mật khẩu chính xác.

Đây chỉ là một ví dụ đơn giản trong số các phương pháp tấn công SQL Injection. Với những thủ thuật phức tạp hơn, kẻ tấn công có thể thêm tài khoản mới, xóa hoặc sửa đổi thông tin của các tài khoản người dùng hiện có. Cùng một phương thức tấn công này, có thể được sử dụng để đánh cắp bản ghi và thông tin cá nhân của người dùng nếu chúng không bị hạn chế đối với người truy cập.

Trong những tình huống nghiêm trọng hơn, khi thiết lập kết nối với máy chủ cơ sở dữ liệu thông qua tài khoản quản trị (như “root” trong MySQL hoặc “sa” trong MS SQL Server), kẻ tấn công có khả năng tiến xa hơn vào hệ điều hành của máy chủ.

Bằng cách sử dụng lỗ hổng SQL injection, kẻ tấn công có thể đồng thời tạo ra tài khoản người dùng trên máy chủ bị xâm nhập, kích hoạt tính năng Remote Desktop, thiết lập thư mục chia sẻ SMB và tải về phần mềm độc hại. Tất cả những hành động này không chỉ làm rối tung dữ liệu đã được lưu trữ trong cơ sở dữ liệu mà còn tạo ra hậu quả nghiêm trọng.

4. Ví dụ thực tế về SQL Injection

Ví dụ trong các trường hợp như: Khi sử dụng mẫu đăng nhập, người dùng cung cấp thông tin, hoặc tại trường tìm kiếm, họ nhập văn bản tìm kiếm, hay khi điền biểu mẫu lưu trữ dữ liệu, người dùng nhập thông tin cần lưu. Tất cả những thông tin này được chuyển vào cơ sở dữ liệu.

Thay vì nhập dữ liệu đúng, hacker tận dụng lỗ hổng để chèn và thực thi các lệnh SQL trái phép nhằm truy xuất dữ liệu của người dùng. SQL Injection được thực hiện thông qua ngôn ngữ lập trình SQL, là ngôn ngữ được sử dụng để quản lý dữ liệu lưu trữ trong toàn bộ cơ sở dữ liệu.

Tuy nhiên, hiện nay, chúng ta thường làm việc trên các framework hiện đại. Tất cả các framework này đều đã được kiểm thử một cách cẩn thận để ngăn chặn các lỗi, bao gồm cả SQL Injection.

Xem thêm:  Svchost.exe là gì? Cách kiểm tra & xử lý virus Svchost.exe

5. Mức độ nguy hiểm của SQL Injection

SQL Injection có thể gây ra những hậu quả nghiêm trọng như:

  • Hack tài khoản cá nhân.
  • Sao chép hoặc ăn cắp dữ liệu từ trang web hoặc hệ thống.
  • Thay đổi dữ liệu nhạy cảm của hệ thống.
  • Xóa dữ liệu quan trọng và nhạy cảm của hệ thống.
  • Đăng nhập vào ứng dụng với tư cách người dùng khác, thậm chí là với vai trò quản trị viên.
  • Xem thông tin cá nhân thuộc về người dùng khác, như chi tiết hồ sơ và các giao dịch của họ.
  • Sửa đổi cấu trúc của cơ sở dữ liệu và thậm chí xóa các bảng trong cơ sở dữ liệu ứng dụng.
  • Kiểm soát máy chủ cơ sở dữ liệu và thực thi lệnh theo ý muốn.

6. Ví dụ tấn công của SQL Injection 

Kẻ tấn công có ý định thực hiện SQL injection sẽ kiểm soát một truy vấn SQL chuẩn, nhằm khai thác những lỗ hổng trong cơ sở dữ liệu do nhập liệu chưa được xác thực. Có nhiều phương pháp để triển khai kỹ thuật tấn công này. Dưới đây là một số cách để thực hiện SQL injection:

Đưa ra ví dụ về trường nhập liệu trước đó, nó có thể dùng để truy xuất thông tin liên quan đến một sản phẩm cụ thể và có thể được thay đổi thành:

http://www.estore.com/items/items.asp?itemid=999 or 1=1

Truy vấn SQL sẽ như sau:

SQL injection la gi
Ví dụ tấn công của SQL Injection

Bởi vì lệnh 1=1 luôn đúng, do đó truy vấn sẽ trả về tất cả các tên và mô tả sản phẩm trong cơ sở dữ liệu, kể cả những tên mà không đáp ứng điều kiện truy cập.

Ngoài ra, các hacker có thể tận dụng việc lọc ký tự không chính xác để biến đổi các lệnh SQL. Một trong những phương pháp này là sử dụng dấu chấm phẩy để phân tách hai trường.

Ví dụ, với input:

http://www.estore.com/items/iteams.asp?itemid=999; DROP TABLE USERS

Truy vấn SQL sẽ như sau:

SQL injection la gi
Ví dụ tấn công của SQL Injection

Kết quả là, toàn bộ cơ sở dữ liệu có thể bị xóa.

Một phương pháp khác để chi phối truy vấn SQL là sử dụng lệnh UNION SELECT. Nó kết hợp hai truy vấn SELECT không có liên quan nhau để trích xuất dữ liệu từ các bảng khác nhau trong cơ sở dữ liệu.

Ví dụ, nếu có input:

http://www.estore.com/items/items.asp?itemid=999 UNION SELECT user-name, password FROM USERS

Truy vấn SQL sẽ như sau:

SQL injection la gi
Ví dụ tấn công của SQL Injection

Bằng việc sử dụng lệnh UNION SELECT, truy vấn này kết hợp yêu cầu thông tin về tên và mô tả của mục hàng 999 với một yêu cầu khác, trích xuất thông tin về tên và mật khẩu của tất cả người dùng trong cơ sở dữ liệu.

7. Những phần dễ bị tấn công SQL Injection 

Các thành phần dễ bị xâm phạm gồm:

  • Form đăng nhập
  • Form tìm kiếm
  • Form nhận xét
  • Mọi trường lưu hoặc trường đầu vào dữ liệu
  • Liên kết trên trang web

Cần chú ý rằng khi thử nghiệm chống lại loại tấn công này, việc kiểm tra chỉ một số trường là không đủ. Ví dụ, một trường có thể được bảo vệ chống lại SQL Injection, nhưng trường khác có thể không. Do đó, quan trọng là không quên kiểm tra tất cả các trường trên trang web.

Xem thêm: DoS, DDoS là gì? | Dấu hiệu, Xử lý & Phòng chống DDoS

8. Cách phòng ngừa SQL Injection

Các cuộc tấn công SQL Injection thường tập trung vào các kênh input mà người dùng sử dụng. Hầu hết các chiến lược phòng ngừa đều liên quan đến quản lý và kiểm soát thông tin đầu vào từ người dùng. Dưới đây là một số biện pháp có thể được triển khai để đảm bảo an toàn cho dữ liệu nhập từ người dùng.

8.1. Không tin tưởng vào input của người dùng

Tất cả thông tin mà người dùng cung cấp cần phải được xem là có thể gây hại, trừ khi có bằng chứng khác. Nguyên tắc này không chỉ áp dụng cho các hộp nhập liệu đơn giản như vùng văn bản, mà còn đối với mọi thành phần khác như dữ liệu ẩn, chuỗi tham số truy vấn, cookie và tệp tải lên.

Trình duyệt không cho phép người dùng tương tác trực tiếp với một đầu vào không có nghĩa là nó không thể bị giả mạo. Các công cụ đơn giản như Burp Suite vẫn giúp người dùng có thể chiếm đoạt các yêu cầu HTTP và chỉnh sửa mọi chi tiết, bao gồm cả các giá trị ẩn, trước khi chúng được gửi đến máy chủ.

Nếu bạn cho rằng sử dụng mã hóa Base 64 để bảo vệ dữ liệu là biện pháp an toàn, hãy nhớ rằng điều này có thể dễ dàng bị giải mã, chỉnh sửa, và sau đó mã hóa lại bởi kẻ tấn công thông minh.

8.2. Xác nhận các chuỗi input ở phía máy chủ

Xác nhận là quá trình đảm bảo rằng dữ liệu nhập từ người dùng là hợp lệ và ngăn chặn bất kỳ lệnh độc hại nào có thể được chèn vào chuỗi nhập. Ví dụ, khi sử dụng PHP, bạn có thể áp dụng hàm mysql\_real\_escape\_string() để tránh những ký tự có thể thay đổi bản chất của lệnh SQL.

Mã đăng nhập có thể được thay đổi như sau:

$con=mysqli_connect(“localhost”,”user”,”password”,”db”);

$username = mysqli_real_escape_string($con, $_POST[‘username’]);

$password = mysqli_real_escape_string($con, $_POST[‘password’]);

$sql_command = “select * from users where username = ‘” . $username; $sql_command .= “‘ AND password = ‘” . $password . “‘”;

Việc chỉnh sửa đơn giản này sẽ bảo vệ code của bạn khỏi cuộc tấn công SQL Injection bằng cách thêm một ký tự (\) trước dấu nháy đơn mà kẻ tấn công có thể chèn vào.

Mặc dù bạn đã tích hợp các chức năng xác thực phía máy khách nhưng không nên lạc quan với việc sử dụng nó như một biện pháp phòng thủ tuyệt vời chống lại cuộc tấn công SQL injection. Chức năng phía máy khách có thể gây khó khăn cho việc gửi dữ liệu nguy hiểm đến máy chủ của bạn, nhưng chúng cũng có thể bị vượt qua dễ dàng thông qua một số điều chỉnh trình duyệt và công cụ khác. Vì vậy, để đảm bảo an toàn, việc thêm xác nhận phía máy chủ là hết sức quan trọng.

Một số nền tảng lập trình, như ASP.NET chẳng hạn, tích hợp các tính năng tự động đánh giá input của người dùng. Tuy nhiên, tin tặc vẫn có khả năng gây hại bằng cách phá hoại các tính năng này. Do đó, việc thực hiện một quy trình kiểm định input của khách hàng một cách chặt chẽ là cực kỳ quan trọng và cần thiết.

SQL injection la gi
Xác nhận các chuỗi input ở phía máy chủ

8.3. Sử dụng các câu lệnh tham số

Để ngăn chặn tấn công SQL Injection, việc sử dụng câu lệnh tham số cũng là một lựa chọn tốt. Các câu lệnh tham số được xác định bằng cách thêm tên của placeholder vào lệnh SQL, sau đó được thay thế bởi input của người dùng. ASP.NET cung cấp một bộ API dễ sử dụng và trực quan để thực hiện điều này.

Mã nguồn dưới đây, viết bằng ngôn ngữ lập trình C#, minh họa cách sử dụng câu lệnh tham số nhằm tăng cường an ninh cho trang web trước nguy cơ tấn công SQL Injection:

SqlCommand cmd = new SqlCommand (“SELECT * FROM users WHERE username=@username AND password=@password”,con);

SqlParameter username = new SqlParameter(); username.ParameterName = “@username”; username.value = txtUsername.Text; cmd.Parameters.Add(username);

SqlParameter password = new SqlParameter(); password.ParameterName = “@password”; password.value = txtPassword.Text; cmd.Parameters.Add(password);

  • Bắt đầu quá trình bằng việc tạo một đối tượng SqlCommand và sử dụng placeholder @parameter_name trong chuỗi lệnh để nhúng dữ liệu người dùng nhập vào.
  • Tiếp theo, tạo một đối tượng SqlParameter, trong đó chứa thông tin input của người dùng, thay vì trực tiếp nhúng nó vào chuỗi lệnh.
  • Cuối cùng, thêm đối tượng SqlParameter vào bộ tham số của đối tượng SqlCommand, điều này sẽ thay thế các tham số bằng input được cung cấp.

8.4. Phân định rõ ràng kiểu input

Cách này áp dụng cho các ngôn ngữ như PHP, nơi bạn thường không xác định rõ kiểu dữ liệu cho các biến.

Việc đặt rõ kiểu dữ liệu cho input là một cách để loại bỏ những dữ liệu có thể làm ảnh hưởng đến câu lệnh SQL. Do đó, nếu bạn mong đợi người dùng nhập “int” cho tham số “age”, bạn có thể đảm bảo tính an toàn của input bằng đoạn mã sau trong PHP:

$age = (int)$_POST[‘age’];

Hãy nhớ rằng đoạn mã này chỉ xác nhận kiểu của input và không kiểm tra phạm vi của nó. Do đó, để đảm bảo người dùng nhập dữ liệu hợp lệ, bạn cần thực hiện mã kiểm tra khác.

Thêm một cách khác là tránh sử dụng dấu nháy đơn trong các lệnh SQL khi không có chuỗi được truyền vào. Thay vì thực hiện mã sau đây…

$sql_command = “select * from users where age = ” . $age;

Sử dụng lệnh sau sẽ an toàn hơn:

$sql_command = “select * from users where age = ‘” . $age . “‘”;

9. Cách ngăn chặn SQL Injection

Vì SQL Injection thường sử dụng các kênh input của người dùng làm kênh tấn công chính, nên phương pháp tiếp cận tốt nhất là kiểm soát và xem xét dữ liệu đầu vào từ người dùng để phát hiện các loại tấn công. Các nhà phát triển cũng có thể tránh các lỗ hổng bảo mật bằng cách áp dụng các biện pháp phòng chống SQL injection như sau:

9.1. Input Validation (Xác thực đầu vào)

Quá trình xác thực được thực hiện để kiểm tra tính hợp lệ của loại dữ liệu mà người dùng gửi đi. Xác thực đầu vào đảm bảo rằng nó tuân theo các yêu cầu về kiểu, độ dài, định dạng, và chỉ có những giá trị đã được xác thực mới được chấp nhận để xử lý. Điều này đóng góp vào việc ngăn chặn bất kỳ lệnh nào được chèn vào chuỗi đầu vào.

Việc xác thực nên được áp dụng đối với các trường cho phép người dùng nhập dữ liệu, và đồng thời, cần quan tâm đến những tình huống sau:

  • Sử dụng biểu thức chính quy như một danh sách trắng cho các dữ liệu có cấu trúc (ví dụ như tên, tuổi, thu nhập, mã bưu chính) để đảm bảo tính hợp lệ của dữ liệu đầu vào.
  • Trong trường hợp có một tập giá trị cố định (như danh sách thả xuống), xác định rõ giá trị được chấp nhận. Dữ liệu đầu vào phải khớp với một trong các tùy chọn được cung cấp.

Dưới đây là cách xác thực tên bảng:

switswitch ($tableName) {

    case ‘fooTable’: return true;

    case ‘barTable’: return true;

    default: return new BadMessageException(‘unexpected value provided as table name’);

}

Biến $tableName có thể được thêm vào trực tiếp, tuy nhiên, giờ đây nó được biết đến là một trong những giá trị hợp pháp cho tên của bảng.

Đối với danh sách thả xuống, quá trình xác thực dữ liệu trở nên đơn giản. Giả sử bạn muốn người dùng chỉ có thể chọn xếp hạng từ 1 đến 5, hãy sửa mã PHP như sau:

<?php

if(isset($_POST[“selRating”]))

{

    $number = $_POST[“selRating”];

    if((is_numeric($number)) && ($number > 0) && ($number < 6))

    {

        echo “Selected rating: ” . $number;

    }

    else

        echo “The rating has to be a number between 1 and 5!”;

}

Bạn đã thêm hai kiểm tra đơn giản:

  • Phải là một số (sử dụng hàm is_numeric()).
  • Giá trị của $number phải lớn hơn 0 và nhỏ hơn 6, đảm bảo rằng điểm nằm trong khoảng từ 1 đến 5.

Dữ liệu nhận được từ bên ngoài phải được xác thực, và nguyên tắc này không chỉ áp dụng cho đầu vào từ người dùng trên Internet mà còn đối với các nhà cung cấp, đối tác và cơ quan quản lý.

SQL injection la gi
Cách ngăn chặn SQL Injection

9.2. Parameterized queries (Tham số hóa truy vấn)

Các truy vấn tham số hóa là một phương tiện để biên dịch trước câu lệnh SQL. Sau đó, bạn có thể cung cấp các tham số để câu lệnh được thực thi.

Phương pháp này hỗ trợ cơ sở dữ liệu nhận diện mã và phân biệt nó với dữ liệu đầu vào.

Dữ liệu đầu vào từ người dùng được tự động trích dẫn, và loại mã hóa này giúp giảm thiểu rủi ro tấn công SQL injection.

Chúng ta cũng có thể sử dụng truy vấn tham số hóa với MySQLi extension, nhưng PHP 5.1 đã giới thiệu một phương pháp làm việc tốt hơn khi tương tác với cơ sở dữ liệu, là PHP Data Objects (PDO). PDO áp dụng các cách tiếp cận đơn giản hóa sử dụng truy vấn tham số hóa. Ngoài ra, nó còn làm cho mã nguồn dễ đọc và dễ di chuyển hơn, bởi vì nó hỗ trợ nhiều loại cơ sở dữ liệu khác nhau, không chỉ giới hạn trong MySQL.

Mã code này sử dụng PDO với truy vấn tham số hóa để tránh lỗ hổng SQL injection:

<?php

$id = $_GET[‘id’];

$db_connection = new PDO(‘mysql:host=localhost;dbname=sql_injection_example’, ‘dbuser’, ‘dbpasswd’);

//preparing the query

$sql = “SELECT username 

            FROM users

            WHERE id = :id”;

$query = $db_connection->prepare($sql);

$query->bindParam(‘:id’, $id);

$query->execute();

//getting the result

$query->setFetchMode(PDO::FETCH_ASSOC);

$result = $query->fetchColumn();

print(htmlentities($result));

9.3. Stored Procedures

Các thủ tục lưu trữ (stored procedures – SP) yêu cầu các nhà phát triển nhóm các lệnh SQL thành một đơn vị logic, nhằm tạo ra một kế hoạch thực thi. Các lần thực thi sau đó cho phép tự động tham số hóa các lệnh. Nói một cách đơn giản, đây là một loại mã có thể được lưu trữ để sử dụng trong tương lai.

Do đó, mỗi khi cần thực hiện một truy vấn, thay vì viết lại mã, bạn có thể gọi đến một stored procedure. Dưới đây là quy trình để tạo một stored procedure trong server MySQL.

Giả sử bạn có một bảng như sau:

CREATE TABLE `salary` (

  `empid` int(11) NOT NULL,

  `sal` int(11) DEFAULT NULL,

  PRIMARY KEY (`empid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Hãy tưởng tượng rằng có một nhân viên cần thu thập dữ liệu tổng hợp về lương của công ty từ bảng đó. Đầu tiên và quan trọng nhất, bạn sẽ cần tạo một người dùng có tên là ‘tr’:

CREATE USER ‘tr’@’localhost’ IDENTIFIED BY ‘mypass’;

Người dùng đó chỉ cần được cấp quyền EXECUTE trên lược đồ chứa bảng đó:

grant execute on hris.*  to tr@`%`

Stored procedure sẽ được tạo như sau:

DELIMITER $$

CREATE PROCEDURE `avg_sal`(out avg_sal decimal)

BEGIN

select avg(sal) into avg_sal from salary;

END

Quá trình tạo một stored procedure avg_sal và lưu trữ nó trong cơ sở dữ liệu được thực hiện thông qua việc phát hành lệnh tạo stored procedure. Để kích hoạt stored procedure từ một ứng dụng PHP, bạn có thể sử dụng PDO:

$db_connection = new PDO(‘mysql:host=localhost;dbname=hris’, ‘tr’, ‘mypass’);

$query = $db_connection->exec(‘call avg_sal(@out)’);

$res = $query->query(‘select @out’)->fetchAll();

print_r($res);

Biến $res sẽ hiển thị mức lương trung bình theo yêu cầu của người dùng. Tiếp theo, người dùng có thể thực hiện quá trình xuất kết quả bằng PHP.

9.4. Sử dụng Escaping

Hãy luôn áp dụng các hàm escape ký tự cho dữ liệu nhập từ người dùng, mà mỗi hệ thống quản lý cơ sở dữ liệu (DBMS) cung cấp. Điều này giúp đảm bảo DBMS không bao giờ nhầm lẫn dữ liệu đầu vào với lệnh SQL do nhà phát triển cung cấp.

Ví dụ: Sử dụng mysql_real_escape_string() trong PHP để tránh các ký tự có thể dẫn đến việc xuất hiện lệnh SQL không mong muốn. Một biện pháp sửa đổi để ngăn chặn login bypass sẽ có dạng như sau:

$db_connection = mysqli_connect(“localhost”, “user”, “password”, “db”);

$username = mysqli_real_escape_string($db_connection, $_POST[‘username’]);

$password = mysqli_real_escape_string($db_connection, $_POST[‘password’]);

$query = “SELECT * FROM users WHERE username = ‘” . $username. “‘ AND password = ‘” . $password . “‘”; 

Trước đó, mã của bạn có thể bị thêm ký tự escape (\) phía trước dấu ngoặc. Tuy nhiên, qua mã trên, bạn sẽ được bảo vệ khỏi các tác động xâm phạm từ người dùng không hợp pháp và giảm thiểu rủi ro SQL injection.

10. Cách diệt tận gốc lỗ hổng SQL Injection

Hãy kiểm tra mã nguồn của từng trang, đặc biệt là ở những nơi mà bạn kết hợp nội dung trang, lệnh, chuỗi, v.v., với dữ liệu từ người dùng. Việc rà soát mã nguồn, tìm kiếm các lỗ hổng bảo mật là một phần không thể thiếu trong quá trình phát triển phần mềm của bạn.

Bạn cũng có thể tận dụng các công cụ quét như sql map để thu thập thông tin về các lỗ hổng SQL injection tiềm ẩn. Trên thực tế, tin tặc thường xuyên sử dụng công cụ này để phát hiện và tận dụng các điểm yếu SQL Injection trên các trang web mục tiêu.

11. Tổng kết

SQL Injection đã tồn tại xung quanh chúng ta trong suốt nhiều thập kỷ và có vẻ như nó sẽ tiếp tục giữ vị trí hàng đầu trong danh sách những lỗ hổng nguy hiểm trong những năm sắp tới. Để bảo vệ chính bạn và người dùng của mình khỏi loại tấn công này, chỉ cần thực hiện một số bước đơn giản, nhưng điều này đòi hỏi một sự tính toán chi tiết. Lỗ hổng này sẽ là một trong những vấn đề hàng đầu cần kiểm tra khi xem xét mã nguồn để đảm bảo an toàn về mặt bảo mật.

Để tránh rơi vào tình trạng trở thành nạn nhân của cuộc tấn công SQL injection tiếp theo, bước đầu tiên là kiểm soát và xác nhận dữ liệu nhập từ người dùng. Sau đó, cần tự trang bị những công cụ cần thiết để bảo vệ trang web của mình.

Hy vọng rằng qua bài viết này bạn đã hiểu rõ SQL Injection là gì. Bạn có thể truy cập vào Blog của VinaHost TẠI ĐÂY để xem thêm nhiều bài viết hấp dẫn khác. Hoặc liên hệ ngay cho chúng tôi khi cần hỗ trợ nhé:

Xem thêm một số bài viết khác:

Bytefence Anti-Malware là gì? Hướng dẫn cách xoá chi tiết

Pentest là gì? Lý do doanh nghiệp không thể thiếu Pentest

Botnet là gì? | Cách phòng chống DDoS Botnet hiệu quả nhất

IP Spoofing là gì? | Phát hiện & Phòng chống IP Spoofing

Đánh giá
5/5 - (6 bình chọn)
Đăng ký nhận tin

Để không bỏ sót bất kỳ tin tức hoặc chương trình khuyến mãi từ Vinahost

    Bài viết liên quan
    Bình luận
    Theo dõi
    Thông báo của
    guest
    0 Góp ý
    Phản hồi nội tuyến
    Xem tất cả bình luận
    Tổng lượt truy cập: lượt xem