Đọc một số câu hỏi và câu trả lời SQL trên SO, tôi thấy this answer cho thấy bạn có thể chuyển đổi đầu vào không tin cậy của người dùng thành hex, do đó bản chất của nó không yêu cầu phải thoát khỏi bất kỳ loại nào và do đó hoàn toàn và hoàn toàn tránh khả năng tiêm SQL.Không sử dụng mã hóa hex để ngăn chặn việc tiêm SQL có bất kỳ điểm yếu nào không?
Lớp trừu tượng cơ sở dữ liệu nào bạn sử dụng (PDO, mysqli, mysql, Pear DB, v.v.) không quan trọng.
Ví dụ về một truy vấn làm việc bình thường:
$DBH = new PDO('mysql:host=127.0.0.1;dbname=test', 'test', 'testpassword');
// could have been:
//$bookTitle = bin2hex($_GET['title']);
$bookTitle = bin2hex('Catch-22');
$query = "SELECT * from `books` WHERE `title` = UNHEX('$bookTitle')";
foreach ($DBH->query($query) as $row) {
echo "\n<br />\n";
print_r($row);
echo "\n<br />\n";
}
Tôi đã bao gồm đủ mã ở đây để bạn có thể nhanh chóng chạy một thử nghiệm nếu bạn có một cơ sở dữ liệu với một bảng như:
CREATE TABLE `books` (`id` INT, `title` VARCHAR(100), `author` VARCHAR(100)) ENGINE=InnoDB CHARACTER SET='utf8';
INSERT INTO `books` VALUES(1, 'Catch-22', 'Joseph Heller');
Tất nhiên điều này là quá đơn giản - bạn thường có xác nhận đầu vào, khử trùng đầu ra và nhiều trừu tượng khác nhưng chúng tôi muốn tập trung vào câu hỏi - không cần thêm lông tơ để giúp cung cấp các ví dụ dễ thực hiện.
Điều tôi muốn biết là nếu có bất kỳ kỹ thuật điểm yếu nào đối với kỹ thuật này. Tôi đặc biệt là không phải hỏi xem kỹ thuật này có điểm yếu của con người hay không (dễ dàng hơn với futz là một lập trình viên cẩu thả, vì rõ ràng nó không sạch như sử dụng các truy vấn được tham số hóa).
Có, tất cả chúng ta có thể đồng ý rằng các truy vấn được tham số hóa ít nhạy cảm với lập trình kém hoặc giám sát không may. Vì vậy, xin vui lòng dính vào câu hỏi - hiện kỹ thuật này giúp tránh tiêm SQL của tất cả các loại, vô điều kiện?
Ai đó có thể hiển thị ví dụ về đầu vào của người dùng có thể phá vỡ kỹ thuật này không? Ngay cả một trường hợp góc, một số cài đặt máy chủ MySQL cụ thể hoặc phiên bản PHP cũ phá vỡ nó?
Nó hoạt động giống như tốt cho thay thế số nguyên:
// could have been:
//$bookID = bin2hex($_GET['id']);
$bookID = bin2hex(1);
$query = "SELECT * from `books` WHERE `id` = UNHEX('$bookID')";
suy nghĩ khác:
Với kỹ thuật này, bạn tránh hai chuyến đi vòng đến cơ sở dữ liệu như xảy ra nếu sử dụng (không bị cạnh tranh) các câu lệnh chuẩn bị (mặc dù các câu lệnh chuẩn bị! = các truy vấn được tham số hóa).
Cẩn thận với một số kỹ thuật được đề xuất khác bắt đầu làm cho một người bị liếc mắt với những trường hợp ngoại lệ ở góc chẳng hạn như this và this. Liệu kỹ thuật mã hóa hex có tránh được mọi khả năng kẻ tấn công tàn phá bằng cách sử dụng các thủ thuật mã hóa ký tự và bất kỳ thứ gì khác không? Có vẻ như giải mã ở phía cơ sở dữ liệu có thể bị giới hạn ở MySQL/MariaDB, mặc dù có thể có third-party solutions for adding UNHEX() to PostgreSQL (hoặc - không chắc chắn - trong một số cơ sở dữ liệu, bạn có thể sử dụng phương pháp khác để đặt các chữ số hex). trong truy vấn mà không sử dụng bất kỳ chức năng
UNHEX
)
Miễn là bạn đang trộn đầu vào của người dùng với cấu trúc truy vấn, bạn là một trong những thông tin bị bỏ lỡ từ một vấn đề lớn. Cho dù bạn sử dụng 'mysql_real_escape_string' hoặc hex, bạn vẫn cần phải bảo vệ tất cả các đầu vào, các câu lệnh được chuẩn bị tự động làm. – DCoder
@DCoder nhưng thấy liên kết hiển thị mysql_real_escape_string có điểm yếu kỹ thuật này không. Tuy nhiên, điểm được thực hiện trên nó được dễ dàng hơn để làm cho những sai lầm @ N.B. có thật không? – messy
Chính xác là 'mysql_real_escape_string' có những điểm yếu nhất định mà kỹ thuật này không có. Tuy nhiên, nó không thay đổi thực tế là các câu lệnh chuẩn bị dễ bảo vệ hơn. Thêm vào đó, các câu lệnh chuẩn bị cũng có thể nhanh hơn vì DB có thể tái sử dụng một kế hoạch truy vấn thay vì phân tích cú pháp mỗi từ đầu. – DCoder