2009-12-01 29 views
5

Đối tác của tôi trên một dự án PHP phản đối thực hành của tôi về việc luôn luôn khử trùng các giá trị số nguyên trong SQL động. Chúng tôi sử dụng các truy vấn được tham số hóa khi có thể. Nhưng đối với các điều kiện UPDATE và DELETE Zend_Db_Adapter yêu cầu một chuỗi SQL không tham số. Đó là lý do tại sao tôi, thậm chí không suy nghĩ, luôn luôn viết một cái gì đó như:Có thể cho phép đôi khi SQL động mà không cần vệ sinh không?

$db->delete('table_foo', 'id = ' . intval($obj->get_id())); 

Đó là tương đương, nhưng là một phiên bản ngắn hơn (Tôi đã kiểm tra mã nguồn ZF):

$db->delete('table_foo', $db->qouteInto('id = ?', $obj->get_id(), 'INTEGER')); 

đối tác của tôi mạnh đối tượng này intval(), nói rằng nếu $obj ID là null (đối tượng chưa được lưu vào DB), tôi sẽ không nhận thấy lỗi, và hoạt động DB sẽ chỉ im lặng thực hiện. Đó là những gì đã thực sự xảy ra với anh ta.

Ông ấy nói rằng nếu chúng tôi khử trùng tất cả các biểu mẫu HTML, không có cách nào ID nguyên có thể xâm nhập vào '; DROP TABLE ...' hoặc ' OR 1 = 1 'hoặc giá trị khó chịu khác và được chèn vào truy vấn SQL của chúng tôi. Vì vậy, tôi chỉ hoang tưởng, và làm cho cuộc sống của chúng ta không cần thiết phức tạp hơn. "Ngừng tin tưởng vào các giá trị $_SESSION sau đó", ông nói.

Tuy nhiên, với điều kiện giá trị chuỗi ông không đồng ý với:

$db->update->(
    'table_foo', 
    $columns, 
    'string_column_bar = ' . $db->qoute($string_value)) 
); 

Tôi thất bại trong việc chứng minh anh ta sai, và ông thất bại trong việc chứng minh tôi sai. Bạn có thể làm được không?

+1

Báo cáo tham số! Các câu lệnh tham số! Các câu lệnh tham số! http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – Cheekysoft

+0

@Cheekysoft Thưa ngài, bạn đã đọc kỹ câu hỏi chưa? Chúng tôi sử dụng các câu lệnh được tham số hóa. Gửi thần chú của bạn đến Zend :) –

+1

Wow! Có vẻ như bạn có thể liên kết trong xóa và cập nhật: http://stackoverflow.com/questions/1845153/zend-framework-how-to-delete-a-table-row-where-multiple-things-are-true –

Trả lời

7

nào làm bạn xem xét nhiều rắc rối:

  • Có để theo dõi một lỗi mà không gây ra một truy vấn SQL thất bại.
  • Có để khôi phục dữ liệu sau khi bạn phạm sai lầm trong việc khử trùng đầu vào biểu mẫu và ai đó khai thác dữ liệu đó.

Cho dù bạn chọn, có câu trả lời của bạn. Cá nhân, tôi có xu hướng nghiêng về phía những điều hoang tưởng của sự vật là tốt.

Nếu có, bạn có thể làm cả hai: tạo hàm của riêng bạn trước tiên kiểm tra giá trị rỗng và sau đó gọi số intval() và sử dụng thay thế đó. Sau đó, bạn có được tốt nhất của cả hai thế giới.

10

Thành thật mà nói, đối tác của bạn đã tắt rocker của mình: khử trùng là rẻ, không có lý do chính đáng để không làm điều đó. Thậm chí nếu bạn đang khử trùng những gì có trong các hình thức HTML, nếu những kiểm tra bằng cách nào đó phá vỡ sản xuất, bạn sẽ được hạnh phúc rằng bạn có một bản sao lưu ở những nơi khác. Ngoài ra, nó khuyến khích một thực hành tốt.

Bạn nên khử trùng — luôn

0

hình thức đầu vào nên IDD luôn được vệ sinh, nhưng không phải mọi biến mà đi vào một truy vấn nên được làm vệ sinh imo ...
Nguồn gốc của biến không đóng một vai trò quan trọng ở đây .

Bạn chỉ cần phải biết nếu các dữ liệu sử dụng có thể được tin cậy ...

0

Nếu bạn nhìn sâu hơn bên trong mã khuôn khổ Zend, bạn sẽ thấy rằng $ db-> quoteInto() biến thành $ db- > quote trả về (chuỗi) intval ($ value) với INTEGER làm kiểu.

Nếu loại không xác định, $ db -> _ quote() được gọi. Mã của nó như sau:

protected function _quote($value) 
{ 
    if (is_int($value) || is_float($value)) { 
     return $value; 
    } 
    return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'"; 
} 

Dù phương thức gọi được sử dụng (có hoặc không có loại chỉ định), $ db-> delete hoàn toàn an toàn.

+0

Doesn ' t vấn đề. delete() với quoteInto (... 'INTEGER') âm thầm nuốt null. –

0

Trước tiên, bạn phải kiểm tra xem ID không phải là không. Nếu có, bạn biết không làm một truy vấn vô ích và tiếp tục từ đó. Nó không có ý nghĩa để theo dõi các vấn đề bằng cách đọc các truy vấn SQL không thành công hay như vậy.

3

Tôi nghĩ rằng đối tác của bạn là sai - ông không được xem xét tách mối quan tâm giữa các dữ liệu sanatisation trong mô hình (nơi mã DB của bạn sống) và dữ liệu xác nhận các hình thức của bạn.

Thông thường, logic xác thực biểu mẫu của bạn sẽ nằm trong một khu vực riêng biệt của ứng dụng với mô hình của bạn. I E. khi thêm trình xác nhận hợp lệ để tạo thành các phần tử và do đó điều này thường được thực hiện trong chính lớp biểu mẫu. Mục đích của lớp mã xác thực này là xác nhận hợp lệ đầu vào của biểu mẫu và trả về các thông báo thích hợp nếu có bất kỳ điều gì sai trái. Vì vậy, tôi nghĩ rằng việc khử trùng dữ liệu trong mô hình nên được xem xét riêng rẽ cho điều này, vì Model thực sự là một lớp độc lập - và do đó phải chịu trách nhiệm về sự khử trùng dữ liệu của chính nó. Vì lý thuyết bạn sẽ có thể tái sử dụng mô hình này ở nơi khác trong ứng dụng của bạn, mô hình không nên giả định rằng việc khử trùng đã được thực hiện ở nơi khác, tức là một phần của lớp xác nhận biểu mẫu.

Điểm chính của đối tác của bạn về việc không nhận thấy các truy vấn SQL không thành công không thực sự là vấn đề trong thực tế - tốt hơn là nên bảo vệ mã.

0

Tất cả dữ liệu được lấy từ biểu mẫu phải được vệ sinh. Không có ngoại lệ. Tất cả dữ liệu được lấy ra từ hệ thống của bạn nên đã được khử trùng trước khi nó xâm nhập vào hệ thống của bạn, và do đó không nên khử trùng khi lấy lại từ hệ thống.

Vì vậy, câu hỏi là - số nguyên này đến từ đâu?

1

Tất nhiên, bạn nên luôn vệ sinh và không dựa vào các biểu mẫu HTML. Điều gì sẽ xảy ra nếu bạn thay đổi mã của mình và sử dụng lại phần đó với một số dữ liệu khác, không phải từ biểu mẫu HTML nhưng từ webservice hoặc email hoặc bất kỳ nguồn nào khác mà bạn quyết định thêm một năm sau đó? Sử dụng intval() ở đây có vẻ là tốt.

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