Приєднуючись до таблиць, я використовую 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§ion=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.
Запитання:
- Який найкращий спосіб запобігти такому сценарію?
- Зараз я переживаю за попередніх клієнтів. Чи можна за допомогою цього коду зробити ще більші ризикові дії, наприклад, таблицю з делатером чи зміною? Я думаю, що не тому, що ви не можете помістити будь-яке інше твердження, ніж SELECT, всередині підселекції, щоб DELETE створив синтаксичну помилку sql. Я правий?
ОНОВЛЕННЯ: Мій приклад не є належним зображенням ін'єкції SQL, оскільки є "знаки навколо $ секцій, і тому зробити ін'єкцію неможливо. У будь-якому випадку це стане можливим, коли очікується ціле значення і коли ви не фільтруєте цілісні введення. Дивіться мій коментар нижче.
'
перед (
знаком завжди буде знак і, таким чином, (SELECT
або що-небудь інше буде таким же строком і не функціонуватиме. Коли поле є цілим числом, '
воно не потрібне, і це можливий такий сценарій. Але ціле число завжди слід фільтрувати, intval()
тому це також не є проблемою.
'
? Так ' AND (SELECT ...) '
? До речі, я не думаю, що Zend це не цитує ... І якщо ви використовуєте прив'язки, тоді PDO впорається з цим. Просто ніколи не використовувати жала конкатенації як це:"sections.section= '$section'"
$db = Mage::getSingleton('core/resource')->getConnection('core_read');
і$db->quote()
навіть у вашому випадку дивитися$db->quoteInto
. Якщо$this
це ресурс, ви могли б зробити:$this->getConnection('core_read')->quoteInto()
якщо ці збори можна зробити:$this->getResource()->getConnection('core_read')->quoteInto()
. по цих лініях. Якщо це допоможе направити вас до своєї мети.