Уразливості введення SQL при використанні моделей SQL Zend Framework


15

Приєднуючись до таблиць, я використовую SQL-моделі Zend Framework. Як приклад я змінив власний код, але думаю, що ви зрозумієте:

$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'); 

Сторінка завантажується ajax, а параметр $ section надсилається як параметр GET ( www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com).

Тепер ось проблема, якщо хтось виконує щось подібне:

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)

Таким чином користувач може скинути всю базу даних. Дані не відображатимуться, але все ж SQL виконає дамп, що може спричинити перевантаження sql.

Запитання:

  1. Який найкращий спосіб запобігти такому сценарію?
  2. Зараз я переживаю за попередніх клієнтів. Чи можна за допомогою цього коду зробити ще більші ризикові дії, наприклад, таблицю з делатером чи зміною? Я думаю, що не тому, що ви не можете помістити будь-яке інше твердження, ніж SELECT, всередині підселекції, щоб DELETE створив синтаксичну помилку sql. Я правий?

ОНОВЛЕННЯ: Мій приклад не є належним зображенням ін'єкції SQL, оскільки є "знаки навколо $ секцій, і тому зробити ін'єкцію неможливо. У будь-якому випадку це стане можливим, коли очікується ціле значення і коли ви не фільтруєте цілісні введення. Дивіться мій коментар нижче.


1
Ви можете використовувати: $db = Mage::getSingleton('core/resource')->getConnection('core_read');і $db->quote()навіть у вашому випадку дивитися $db->quoteInto. Якщо $thisце ресурс, ви могли б зробити: $this->getConnection('core_read')->quoteInto()якщо ці збори можна зробити: $this->getResource()->getConnection('core_read')->quoteInto(). по цих лініях. Якщо це допоможе направити вас до своєї мети.
попіл

Я щойно зрозумів, що цей сценарій можливий, лише якщо значення є цілим числом. Якщо значення - varchar, то 'перед (знаком завжди буде знак і, таким чином, (SELECTабо що-небудь інше буде таким же строком і не функціонуватиме. Коли поле є цілим числом, 'воно не потрібне, і це можливий такий сценарій. Але ціле число завжди слід фільтрувати, intval()тому це також не є проблемою.
JohnyFree

Що робити, якщо ви почнете із закриття '? Так ' AND (SELECT ...) '? До речі, я не думаю, що Zend це не цитує ... І якщо ви використовуєте прив'язки, тоді PDO впорається з цим. Просто ніколи не використовувати жала конкатенації як це:"sections.section= '$section'"
7ochem

@ 7ochem у такому випадку ви ОБОВ'ЯЗКОВО прив’язати параметр за допомогою? і "стане \". Але якщо ви використовуєте ціле значення, ви не прив'язуєте його, оскільки ви можете очистити його за допомогою функції php intval () і 'щось стане 0.
JohnyFree

Відповіді:


8

Підтвердьте свій внесок!

Наскільки добре і скільки завгодно.

Деякі пропозиції щодо вашої перевірки:

  1. Перевірте довжину отриманої змінної за допомогою GET-параметра. Не потрібно приймати довгу довгу струну.

  2. Підтвердження для доменного імені. Який формат мають ваші очікувані доменні імена? Це завжди www.mydomain.tld? Створіть регулярний вираз, який перевіряє відповідність чи (краще) використання Zend_Validate_Hostname:

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
  3. Білий список: чи знаєте ви, яких доменних імен очікувати? Ви можете створити список дозволених доменів і перевірити їх. Решту киньте.

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. Чорні списки доменних імен та чи символів: Якщо ви очікуєте доменного імені, не потрібно приймати жодні інші символи, крім az та 0-9 та "." (якщо ви не працюєте зі спеціальними доменними іменами).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.