Pull to refresh

Comments 11

Не стоит бездумно кидать рефакторить.
В книге «Чистый питон» есть такая рекомендация:

Если форматирующие строки поступают от пользователей, то используйте шаблонные строки, чтобы избежать проблем с безопасностью.
В противном случае используйте интерполяцию литеральных строк при
условии, что вы работаете с Python 3.6+, и «современное» форматирование строк — если нет.

Здесь под интерполяцией литеральных строк, автор имеет в виду f-string
Под «современным» понимается: 'Привет, {}'.format(name)
>>> SECRET = 'это – секрет'
>>> class Error:
... def __init__(self):
... pass
>>> err = Error()
>>> user_input = '{error.__init__.__globals__[SECRET]}'
# Ой-ей-ей...
>>> user_input.format(error=err)
'это – секрет'



защита


>>> user_input = '${error.__init__.__globals__[SECRET]}'
>>> Template(user_input).substitute(error=err)
ValueError:
"Invalid placeholder in string: line 1, col 1" 
Я может что-то не понимаю, но использовать пользовательский ввод в качестве шаблона строк — это потенциальная уязвимость со времен функций *prinf в C.
Не надо так.
PS: лично я использую str.replace и re.sub в этих случаях.

Этот пользовательский ввод может быть локализацией с закладкой. Ревью локализуемых текстов может быть более расслабленным, чем ревью основного кода, так как мало кто вообще подозревает, что в таких текстах может быть код

Довольно интересный пример, но, как я понял, flynt меняет строки на fстроки, которые являются константными литералами, тоесть подобная уязвимость к ним не применима.
F-strings работают только на Python 3.6+, но скоро это не будет проблемой так как другие версии устареют.

Согласно: devguide.python.org/#status-of-python-branches
2.7 — да 2020-01-01 — RIP.
Но 3.5 — еще до 2020-09-13.

Поэтому я бы не торопился с переводом питоновского кода (даже если он уже на под 3+ версию заточен) на фичи, которые поддерживаются только в 3.6+

Я бы подождал хотя бы еще пол годика после 2020-09-13 да и то в некоторых местах 3.5 и ниже могут еще довольно долго жить.
Спасибо за статью, я вот как-то упустил появление f-string. Хотя хотелось бы увидеть более полное раскрытие темы — для меня осталось непонятным, почему f-string такие быстрые.
Если найду время покопаю глубже и напишу еще статью. Что я уже знаю: f-strings не парсят шаблон для того, чтобы найти куда вставить переменную — в Abstract Syntax Tree они называются JoinedString, и содержал лист выражений, которые будут соединены в одну строку. Например f«Hello {world}» образует лист из [ast.Str ('Hello '), ast.FormattedValue (value=world)]. F-strings парсятся только один раз при начальной интерпретации файла. Метод .format получает строку как аргумент и парсит каждый раз, а на f-string возможны оптимизации (исходник превратится в .pyc).
Спасибо, в целом я понял из этого описания. :)
прикольно, то что в скобках просто исполняется поэтому должны быть защищено от XXS атак на питон))
Кстати, f-strings могут быть вложенными
f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
Sign up to leave a comment.

Articles