tra-loi-cau-hoi-phat-trien-web.com

Các mũi tiêm SQL sử dụng Jfactory :: getDBO và setQuery ()

$db = JFactory::getDBO();
$searchP = JRequest::getVar('key');
$sql = "SELECT name FROM people LIKE " . "'%" . $searchP . "%'";

$db->setQuery($sql);
$fileR = $db->loadObjectList();

SetQuery () sẽ đưa ra lỗi khi có hai câu lệnh SQL trong cùng một chuỗi?

Ví dụ, theo mã của tôi, có thể thực hiện lệnh thả bảng bằng cách chuyển tham số truy vấn này hoặc một cái gì đó tương tự:

key=a'; DROP TABLE people; # 

Hơn nữa sẽ sử dụng một cái gì đó như

$db = JFactory::getDBO();
$query = $db->getQuery(true); 
$query ->setLimit('1');
$query ->select($db->quoteName('name'));
$query ->from($db->quoteName('people'));
$query ->like($db->quoteName($searchP));
$db->setQuery($query);

ngăn tiêm vì giới hạn truy vấn của đối tượng truy vấn đang được đặt thành 1?

5
Jay Shri

Bạn sẽ không cần phải lo lắng về các cuộc tấn công tiêm sql nếu bạn sử dụng quote() (hoặc q()) và quoteName() (hoặc qn()) phương pháp phù hợp.

Từ https://docs.j Joomla.org/Secure_coding_guferences#Secure_on_search

Bảo mật khi tìm kiếm

Cần chú ý đặc biệt đến các mệnh đề THÍCH có chứa ký tự% ký tự đại diện vì các mệnh đề này yêu cầu thoát đặc biệt để tránh các cuộc tấn công từ chối dịch vụ có thể xảy ra. Mệnh đề THÍCH có thể được xử lý như thế này:

// Xây dựng thuật ngữ tìm kiếm bằng cách thoát khỏi chuỗi do người dùng cung cấp và, nếu được yêu cầu, hãy thêm% ký tự đại diện.

$search = '%' . $db->escape( $search, true ) . '%' );

// Xây dựng truy vấn SQL, cẩn thận ngăn chặn hành vi mặc định của Trích dẫn để tránh thoát kép.

$query = 'SELECT  * FROM #__table WHERE `field` LIKE ' . $db->quote( $search, false );

->like(), theo như tôi đã nghiên cứu, không tồn tại. Vì vậy, dựa trên đề xuất tài liệu ở trên và giả sử bạn muốn tìm kiếm cột name, tôi sẽ đề xuất khối mã sau:

$db = JFactory::getDBO();
$query = $db->getQuery(true)
            ->select($db->qn('name'))
            ->from($db->qn('people'))
            ->where($db->qn('name') . ' LIKE ' . $db->q('%' . $db->escape($searchP, true) . '%', false));
$db->setQuery($query);

Khi thực hiện truy vấn LIKE thường rất hợp lý khi nhận nhiều hàng dữ liệu trong tập kết quả. Vì tôi tin rằng bạn chỉ đơn thuần sử dụng phương thức setLimit() để phòng ngừa bảo mật, tôi sẽ xóa nó để truy vấn được cải thiện.


Bất chấp những gì bình luận của inf3rno trạng thái, không có phương thức bind() có sẵn theo Tài liệu mới nhất . (Tôi đã kiểm tra đoạn mã bằng cách nào đó bằng cách sử dụng cả :needle? với tư cách giữ chỗ và nhận được: Lỗi nghiêm trọng: Gọi tới hàm thành viên liên kết () trên null) Tôi ước nó không phải theo cách này bởi vì trước khi vào Joomla-land, tôi sẽ sử dụng các câu lệnh được chuẩn bị với trình giữ chỗ cho TẤT CẢ dữ liệu bên ngoài/không đáng tin cậy được cung cấp cho các truy vấn của tôi.

Một bài đăng có liên quan từ Lodder từ 2014 liên quan đến các tuyên bố đã chuẩn bị trong Joomla.

Mục đích/tác dụng của phương thức quote (esc ()) trong khối mã của tôi ở trên là để đảm bảo rằng bất kể chuỗi nào được chuyển đến truy vấn, chuỗi luôn được coi là một giá trị trong biểu thức. Điều này có vẻ như tương đương với mysqli_real_escape() (nhưng tôi đã không kiểm tra dưới trình duyệt Joomla). Thật không may, nhiều nhà phát triển StackOverflow gắn cờ mysqli_real_escape() là tối ưu phụ và đề xuất các câu lệnh được chuẩn bị với trình giữ chỗ thay thế. Tôi sẽ cập nhật tất cả các dự án Joomla của mình ngay khi phương thức bind() khả dụng.


Tôi đã chạy thử nghiệm sau trên Joomla 3.8.6 của mình:

$needle = "key=a'; INSERT INTO [... redacted query that would be successful on its own ...]; #";
try {
    $db = JFactory::getDbo();
    $sql = "SELECT [redacted] FROM [redacted] WHERE [redacted] LIKE " . "'%" . $needle . "%'";
    $db->setQuery($sql);
    var_export($db->loadAssocList());
} catch (Exception $e) {
    echo $e->getMessage();
}

và nhận được:

1064 Bạn có lỗi trong cú pháp SQL của bạn; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết đúng cú pháp để sử dụng gần 'INSERT INTO

Điều này chỉ ra rằng phương thức setQuery() của Joomla sẽ bóp nghẹt nhiều truy vấn.

6
mickmackusa