Подтвердить что ты не робот

SQLAlchemy + SQL Injection

Каковы наилучшие методы снижения атак SQL-инъекций при использовании SQLAlchemy?

4b9b3361

Ответ 1

Если у вас есть специальные символы (например, точки с запятой или апострофы) в ваших данных, они будут автоматически указываться для вас Объект SQLEngine, поэтому вам не нужно беспокоиться о цитировании. Это также означает что, если вы намеренно не обходите Механизмы цитирования SQLAlchemy, Атаки SQL-инъекций в основном невозможно.

[per http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html]

Ответ 2

TL;DR: Избегайте необработанного SQL как можно больше.

Принятый ответ ленив и неверен. Метод фильтра принимает необработанный SQL, и если он используется таким образом, он полностью восприимчив к атакам SQL-инъекций. Например, если вы должны принять значение из URL-адреса и объединить его с сырым sql в фильтре, вы можете атаковать:

session.query(MyClass).filter("foo={}".format(getArgs['val']))

используя приведенный выше код и приведенный ниже URL, вы будете вводить SQL в свой оператор фильтра. Приведенный выше код вернет все строки в вашей базе данных.

http://domain.com/?val=2%20or%201%20=%201

Ответ 3

Добавить в ответ @Tendrid. Я сделал небольшое исследование, используя тихий наивный подход. filter метод имеет *criterion в качестве аргумента, несколько других методов ORM Query имеют схожие аргументы.

В случае аргумента filter метод *criterion аргумент заканчивается переданным в _ literal_as_text, который в случае строки указывает на его безопасность sql (пожалуйста, поправьте меня, если я ошибаюсь). Поэтому он делает его небезопасным.

Вот результат исследование метода класса ORM с аргументом *criterion:

filter   - uses _literal_as_text (NOT SAFE)
having   - uses _literal_as_text (NOT SAFE)

distinct - uses _literal_as_label_reference (NOT SAFE)
group_by - uses _literal_as_label_reference (NOT SAFE)
order_by - uses _literal_as_label_reference (NOT SAFE)

join     - uses model attributes to resolve relation (SAFE)

Примеры возможных пропусков метода (чтобы это было просто, форматирование строк пропущено):

db.session.query(User.login).group_by('login').having('count(id) > 4; select name from roles').all()
db.session.query(User.login).distinct('name) name from roles /*').order_by('*/').all()
db.session.query(User.login).order_by('users_login; select name from roles').all()
db.session.query(User.login).group_by('login union select name from roles').all()