2012-11-01 28 views
7

Tôi bị cắn lỗi thoát sql đầu tiên của mình (đã quá trễ) khi tôi cố gắng thực hiện truy vấn PostgreSQL dưới đây với một giá trị chứa dấu nháy đơn ví dụ. O'Brien, sử dụng FreePascal và LazarusCó thư viện để khử trùng các tham số truy vấn cho PostgreSQL hoặc SQL nói chung, cho FreePascal và Delphi không?

SQL.Add(format('select * from zones where upper(zn_name) >= %s and upper(zn_name) < %s order by zn_name',[sQuote(zoneMin), sQuote(zoneMax)])); 

Trong các truy vấn trên SQuote là một chức năng bọc lấy một chuỗi trong dấu ngoặc đơn. Có một số thư viện tiêu chuẩn để khử trùng các tham số truy vấn SQL cho Lazarus/FreePascal hoặc Delphi cho vấn đề đó không?

+0

Bạn có thể sử dụng chức năng 'QuotedStr' (thử sql-inject ...) – kobik

Trả lời

16

Ứng dụng của bạn dễ bị tấn công nghiêm trọng về các vấn đề bảo mật được gọi là SQL injection. Xem http://bobby-tables.com/.

Chắc chắn, O'Brian gây ra lỗi, nhưng còn khoảng ');DROP SCHEMA public;-- thì sao? Hoặc ');DELETE FROM users;--? Người đầu tiên không nên làm việc vì ứng dụng của bạn nên không bao giờ chạy với tư cách là người siêu người dùng hoặc người sở hữu bảng, nhưng ít nhà thiết kế ứng dụng thực hiện nỗ lực thực sự làm điều đó và thường chạy người dùng đặc quyền trong sản xuất. Cái thứ hai sẽ hoạt động trong hầu hết các ứng dụng; xem phần cuối của bài đăng để biết chi tiết.

Các biện pháp đơn giản nhất và phòng ngừa tốt nhất là sử dụng báo cáo tham số* trong thư viện khách hàng của bạn. Xem this example cho Delpi:

To use a prepared statement, do something like this: 

query.SQL.Text := 'update people set name=:Name where id=:ID'; 
query.Prepare; 
query.ParamByName('Name').AsString := name; 
query.ParamByName('ID').AsInteger := id; 
query.ExecSQL; 

(Tôi chưa bao giờ sử dụng Delphi và cuối cùng đã viết mã Pascal vào năm 1995; Tôi chỉ trích dẫn ví dụ đưa ra).

Điều bạn đang làm hiện tại là nội suy chuỗi thông số. Nó là rất nguy hiểm. Nó có thể được thực hiện một cách an toàn chỉ khi bạn có một chức năng mạnh mẽ cho trích dẫn các ký tự SQL, không chỉ trích dẫn ở mỗi đầu, mà còn xử lý các lần thoát khác, tăng gấp đôi ngoặc kép, v.v. nó là mạnh mẽ thích hợp hơn để sử dụng câu lệnh được tham số hóa.


Đây là bản mở rộng của ví dụ tôi đã nêu ở trên. Giả sử bạn đang làm một cách hoàn hảo chèn thông thường của người dùng bằng tên, nơi 'Fred' là một ví dụ tên đầu vào của khách hàng:

INSERT INTO users (user_name) VALUES ('Fred'); 

Bây giờ một số người khó chịu sẽ gửi tên người dùng ');DELETE FROM users;--. Đột nhiên ứng dụng của bạn đang chạy:

INSERT INTO users (user_name) VALUES ('');DELETE FROM users;--'); 

mà khi mở rộng là:

INSERT INTO users (user_name) VALUES (''); 
DELETE FROM users; 
--'); 

hay nói cách khác một chèn rằng chèn một chuỗi rỗng (mặc dù họ có thể cũng giống như dễ dàng đặt một tên người dùng hoàn toàn hợp lệ trong) , theo sau là tuyên bố DELETE FROM users; - xóa tất cả các hàng trong users - sau đó nhận xét không làm gì cả. Splat. Có dữ liệu của bạn.


* statemments tham số đôi khi không đúng cách gọi là chuẩn bị phát biểu.Điều đó là không chính xác bởi vì một câu lệnh chuẩn bị không nhất thiết phải được tham số hóa và một câu lệnh được tham số hóa không nhất thiết phải được chuẩn bị. Sự nhầm lẫn đã phát sinh bởi vì các giao diện cơ sở dữ liệu của nhiều ngôn ngữ không cung cấp một cách để sử dụng các câu lệnh được tham số hóa mà không cần sử dụng các câu lệnh đã chuẩn bị.

+2

Hơn thế nữa, thiết kế tương tự các thư viện tồn tại cho PHP (trên các bước đầu tiên để làm chủ nó) và tất cả các ngôn ngữ kịch bản web khác. Nó cũng giải quyết vấn đề tose của chuỗi thoát, đại diện DATE khác nhau và như vậy. "Sanitizing" thông số là quảng cáo hoc "người đàn ông nghèo" thay thế cho các thông số rõ ràng tách. Nếu bạn thấy mã của ai đó với "khử trùng" thay thế thì hầu hết có lẽ anh ta hoặc không nhận được thư viện hiện đại hoặc chỉ không nhận được bảo mật. –

+0

Tôi hỏi câu hỏi này bởi vì tôi biết đây là một bãi mìn ngay cả đối với những người nghĩ rằng họ có vấn đề liên kết. Tôi biết về các truy vấn được tham số hóa, nhưng muốn biết liệu chúng có được đảm bảo an toàn không, một số người hiểu biết hơn cũng có thể lừa chúng. – vfclists

+2

@vfclists Việc sử dụng đúng các truy vấn được tham số hóa hoàn toàn sẽ ngăn chặn các cuộc tấn công SQL injection * trừ khi SQL động được thực thi trong cơ sở dữ liệu *, bằng câu lệnh PL/pgSQL 'EXECUTE'. Nếu bạn đang sử dụng SQL động trong DB, bạn cần bảo vệ chống lại SQL injection ở đó, với việc sử dụng cẩn thận định dạng '% I' của hàm' format' và với 'EXECUTE ... USING'. Xem câu trả lời trước cho vấn đề đó: http://stackoverflow.com/a/12995424/398670. –

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