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 ответов

26 просмотров

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

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

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

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

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

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

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

Tishka17
это радует

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

Tishka17
gettext, babel

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

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

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

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

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

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

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

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта