2015-06-29 13 views
7

Đọ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ư thisthis. 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)

+2

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

+0

@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

+1

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

Trả lời

-3

có vẻ hợp lý vì tất cả các dữ liệu, ngay cả những người sử dụng đầu vào có thể gây ra tiêm, sẽ được chuyển đổi.Tôi đã cố gắng tìm cách bỏ qua nó nhưng tôi không thể. Cho đến nay những bất lợi lớn nhất tôi thấy là: 1) Từ một khung nhìn cơ sở dữ liệu, bạn sẽ không thể hiểu được đầu vào của người dùng. Bạn sẽ lấy tất cả mọi thứ từ DB và chuyển đổi nó chỉ để xem nó hoặc thao tác nó. 2) Bất kỳ đầu vào nào bạn cung cấp, độ dài chuỗi sẽ tăng gấp đôi sau khi chuyển đổi.

+2

Bạn đã thực sự thử nghiệm nó chưa? - Bởi vì ý kiến ​​của bạn chỉ ra rằng bạn đã không nhận thấy rằng các dữ liệu trong các bảng là không trong hex. Hex chỉ là mã hóa chuyển trong lược đồ này. – messy

1

Chúng tôi sử dụng kỹ thuật mã hóa hex này trên hệ thống thương mại điện tử đã hoạt động trong vài năm.

Tôi chưa gặp bất lợi và khi bạn có đối tượng được viết cho mỗi bảng trong cơ sở dữ liệu (với chức năng lưu trữ &), tất cả đều bị ẩn khỏi các nhà phát triển giao diện người dùng, họ thực sự không ' t thậm chí thông báo.

một Kỹ thuật này làm việc cho

  1. chặn SQL-Injection
  2. hỗ trợ mã hóa ký tự bất kỳ của khách hàng
  3. lưu trữ dữ liệu nhị phân

của nó cũng rất nhanh (chúng tôi đã xem xét mã hóa base64, sẽ tạo ra các chuỗi SQL ngắn hơn, nhưng yêu cầu nhiều CPU hơn). Trong các thử nghiệm, chúng tôi thấy không có sự khác biệt hiệu suất đo lường giữa mã hóa hex tất cả đầu vào chuỗi và không.

kỹ thuật này có giúp tránh việc tiêm SQL tất cả các loại, vô điều kiện không?

Tôi chưa nhìn thấy như thế nào ai có thể SQLI nếu kỹ thuật này đã được luôn sử dụng (khi ràng buộc bất kỳ dữ liệu bên ngoài vào một câu lệnh SQL) -

Như là chung cho tất cả các kỹ thuật (DCoder) - nó phải được sử dụng phổ biến để cung cấp khả năng bảo vệ phổ quát - mysql_real_escape_string cũng chịu đựng điều này.

người dùng "N.B" rants, nhưng không cung cấp đối số kỹ thuật (có thể anh ta đang nói về PokemonGo vs CSGO, ai biết được?), Và câu trả lời duy nhất hiểu lầm rõ ràng kỹ thuật.

Tuy nhiên, tôi thấy thiếu người sử dụng/ghi lại kỹ thuật này rất đáng ngạc nhiên - đây là lý do duy nhất tôi có bất kỳ nghi ngờ gì về nó. Nó đơn giản, dễ dàng, toàn diện và cung cấp một loạt các lợi ích hữu ích khác, thật khó để có được vòng đầu của tôi tại sao mọi người không làm điều đó và SQLi là một điều của quá khứ?

+0

Lý do rất đơn giản: phương pháp này không tốt hơn định dạng chuỗi thông thường và kém hơn so với ràng buộc. Vì vậy, tại sao bận tâm với "sử dụng/tài liệu" ở tất cả? –

+0

@YourCommonSense của bạn "tồi tệ" hơn vì dễ mắc lỗi khi viết mã. Những gì bạn đã không đề cập đến là nó về mặt kỹ thuật tốt hơn so với mysql_real_escape_string (xem các liên kết trong câu hỏi) và theo như tôi có thể thấy, về mặt kỹ thuật bằng cách sử dụng các truy vấn tham số. – messy

+0

@messy để bạn hiểu sai sai –

Các vấn đề liên quan