170 похожих чатов

Про форматирование и инъекции. В Python есть минимум 3 разных способа

форматирования строк:
* f-строки
* .format
* %

Мы их часто используем для формирования текста, как человеко-читаемого, так и понятного компьютеру.
Если с формированием текста для человека скорее всего больших проблем нет. В худшем случае человеку придется приложить дополнительные усилия, чтобы понять, что он видит.
То с формированием текста для компьютера мы рискуем получить строку, которую он просто не сможет понять или поймет неверно. В том числе это может привести к порче или утечке данных.

Компьютер ожидает, что обрабатываемый текст будет оформлен согласно определенным правилам и вы не можете просто так вставить туда произвольную строку не нарушив при этом структуру текста.
Речь идет о формировании SQL, XML, HTML, JSON, консольной команды, URL, регулярных выражений и ещё кучи различных типов строк.

Как правило такая проблема решается одним из двух способов:
1. Ручное экранирование данных
2. Вызов специальных библиотечных методов, подставляющих данные безопасно.

Как правило лучше выбирать второй способ, так он проще и оставляет меньше шансов ошибиться.

Рассмотрим примеры.

1. SQL
Допустим вы хотите прочитать данные из БД и пишете такой запрос:
cur.execute(f"SELECT * FROM users WHERE login = '{somelogin}'")
Он будет работать в каких-то случаях и обязательно сломается, если переменная somelogin будет содержать, например, кавычку.
В некоторых случаях это может привести к исполнению произвольного SQL кода.

Замена f-строки на .format или форматирование через % ничего не изменит.
Правильно тут было бы сделать так (использовать тут ? или другой символ зависит от вашей СУБД):
cur.execute("SELECT * FROM users WHERE login = ?", (somelogin,))

2. HTTP
Если вы делаете GET запрос, вы можете напистаь такой код:
requests.get(f"http://site.com?search={query}")
Он будет работать некорректно если переменная query, например, содержит знаки &?
Правильно написать так:
requests.get("http://site.com", params={"search": query})

3. Shell
Следующий код сломается если имя папки содержит пробел ил точку с запятой и может привести к исполнению произвольных команд.
subprocess.run(f"ls {dirname}")
Его стоит заменить на
subprocess.run(["ls", dirname])

4. HTML
В случае подстановки данных в HTML стоит воспользоваться специальными шаблонизаторами. Например, jinja.


Доп материалы:
* https://xkcd.ru/327/
* https://ru.wikipedia.org/wiki/Внедрение_SQL-кода
* https://ru.wikipedia.org/wiki/Межсайтовый_скриптинг

#faq

23 ответов

19 просмотров

Ну наконец свою пасту написал\

Ничего нового не узнал после прочтения

только в первом subprocess.run ты shell=True забыл. в позиксах без него работать не будет.

а если надо добавить имя таблицы из переменной, тоже можно '?' использовать? или . format. у меня просто с? не получилось в запрос имя таблицы воткнуть из переменной

Надо бы такие пасты собирать в какую-то общую базу,

TitsFoxy
а если надо добавить имя таблицы из переменной, то...

имя таблицы в запрос динамически подставлять практически никогда не надо

Tishka17
это радует

Лучше подскажи чем можно сделать мультиязычность в программе, без лишнего гемора, или уже придётся писать свою библиотеку?

Tishka17
gettext, babel

да gettext какой-то гемор как по мне

Alex
имя таблицы в запрос динамически подставлять практ...

у меня прост имя таблицы это id чата, чтоб различались они для каждого чата своя таблица. Лучше не придумала ничего:(

Tishka17- Автор вопроса

Даже удивительно что тут нет os.path) Моя личная боль urljoin - вроде и юзаю не первый месяц, но тупые ошибки появляются)

TitsFoxy
у меня прост имя таблицы это id чата, чтоб различа...

пора тебе открыть для себя нормальные формы.

Tishka17- Автор вопроса

Похожие вопросы

Обсуждают сегодня

Ребят в СИ можно реализовать ООП?
Николай
32
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Всем доброго вечера. Разрабатываю 32 раз. приложение в Delphi. Столкнулся с тем, что стандартный  TFilestream  не работает с большим файлом > 2 ГБайт (после вызова функции see...
Vadim Gl
16
добрый день. Подскажите, есть сайт на 1.4.7 и я хочу обновиться, особо ничего не меняя. мне выбирать версию 1.4.35 или третью ветку? и можно ли обновлять "как есть", или нужно...
Digital Cat
12
народ, плиз хелп, всю голову сломал себе уже... разве может быть так, что GetProcAddress( GetModuleHandle( "kernel32.dll" ), "SetThreadDescription" ) вернёт ненулевое значение...
Iluha Companets
12
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
а плаксы из-под питона умеют только в комфортных условиях что-то выдавить из себя?)
Lencore
9
Кстати, что за тип булеана, который в памяти как 00 для фолса и 01 для тру отображается? Однобайтовый
Serjone
8
ребят подскажите почему матрица не транспонируется? #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> #include <locale.h> #define N 7 int main() { int...
† C E †
1
Карта сайта