Lỗ hổng SQL tiêm khi sử dụng các mô hình SQL của Khung công tác Zend


15

Khi tham gia các bảng, tôi sử dụng các mô hình SQL của Khung công tác Zend. Ví dụ tôi đã sửa đổi mã thực tế của mình, nhưng tôi nghĩ bạn sẽ nhận được điểm:

$this->getSelect()->join(
                      array('sections' => $sectionsTableName),
                      'main_table.banner_id = pages.banner_id',
                      array()
                    )
                  ->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
                  ->group('main_table.banner_id'); 

Trang được tải với ajax và tham số phần $ được gửi dưới dạng tham số GET ( www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com).

Bây giờ đây là vấn đề nếu ai đó thực hiện một cái gì đó như thế này:

www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

Bằng cách này, người dùng có thể kết xuất toàn bộ cơ sở dữ liệu. Dữ liệu sẽ không được hiển thị, nhưng SQL vẫn sẽ thực hiện kết xuất có thể gây quá tải sql.

Câu hỏi:

  1. Cách tốt nhất để ngăn chặn kịch bản như vậy là gì?
  2. Bây giờ tôi lo lắng cho khách hàng trước. Là với mã này có thể thực hiện nhiều hành động rủi ro hơn, như delate hoặc thay đổi bảng? Tôi đoán không phải vì bạn không thể đặt bất kỳ câu lệnh nào khác ngoài CHỌN bên trong subselect để DELETE sẽ tạo ra lỗi cú pháp sql. Tôi có đúng không

CẬP NHẬT: Ví dụ của tôi không phải là minh họa thích hợp cho việc tiêm SQL vì có 'dấu hiệu arround $ và do đó sẽ không thể thực hiện tiêm. Dù sao, điều này sẽ có thể khi mong đợi giá trị số nguyên và khi bạn không lọc đầu vào số nguyên. Xem bình luận của tôi dưới đây.


1
Bạn có thể sử dụng: $db = Mage::getSingleton('core/resource')->getConnection('core_read');$db->quote()thậm chí trong trường hợp của bạn nhìn vào $db->quoteInto. Nếu $thislà một tài nguyên, bạn có thể làm: $this->getConnection('core_read')->quoteInto()nếu đó là một bộ sưu tập bạn có thể làm : $this->getResource()->getConnection('core_read')->quoteInto(). dọc theo những dòng đó. Nếu điều đó giúp hướng dẫn bạn hướng tới mục tiêu của bạn.
tro

Tôi chỉ nhận ra rằng kịch bản này chỉ có thể nếu giá trị là số nguyên. Nếu giá trị là varchar, thì sẽ luôn có 'dấu trước khi (ký và do đó (SELECThoặc bất cứ thứ gì khác sẽ chỉ là chuỗi và không phải là hàm. Khi trường là số nguyên, thì 'không cần thiết và nó có thể xảy ra kịch bản như vậy. Nhưng số nguyên phải luôn được lọc với intval()vì vậy đây cũng không phải là vấn đề.
JohnyFree

Điều gì nếu bạn bắt đầu với việc đóng cửa '? Vậy ' AND (SELECT ...) 'sao Nhân tiện, tôi không nghĩ Zend không trích dẫn điều này ... Và nếu bạn sử dụng các ràng buộc, thì PDO sẽ xử lý việc này. Chỉ cần không bao giờ sử dụng cách ghép nối như thế này:"sections.section= '$section'"
7ochem

@ 7ochem trong trường hợp như vậy bạn PHẢI ràng buộc tham số bằng cách sử dụng? và 'sẽ trở thành \'. Nhưng nếu bạn sử dụng giá trị số nguyên, thì bạn không liên kết nó vì bạn có thể làm sạch nó bằng hàm php intval () và 'một cái gì đó sẽ trở thành 0.
JohnyFree

Câu trả lời:


8

Xác thực đầu vào của bạn!

Càng tốt và càng nhiều càng tốt.

Một số gợi ý để xác nhận của bạn:

  1. Kiểm tra độ dài của biến bạn nhận được thông qua tham số GET. Không cần phải chấp nhận một chuỗi dài không bao giờ hết.

  2. Xác thực cho một tên miền. Tên miền dự kiến ​​của bạn có loại định dạng nào? Có phải luôn luôn là www.mydomain.tld? Tạo một biểu thức chính để kiểm tra sự trùng khớp hoặc (tốt hơn) sử dụng Zend_Validate_Hostname:

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
  3. Danh sách trắng: Bạn có biết những tên miền nào được mong đợi không? Bạn có thể tạo một danh sách các tên miền được phép và kiểm tra lại chúng. Thả phần còn lại.

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. Danh sách đen và tên miền hoặc ký tự: Nếu bạn mong đợi một tên miền, không cần phải chấp nhận bất kỳ ký tự nào khác ngoài az và 0-9 và "." (trừ khi bạn đang làm việc với các tên miền đặc biệt).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.