Я работаю над веб-приложением, где пользователи смогут отправлять строки, которые затем будут заменять на сервер.
Я хотел бы использовать синтаксис формата PEP 3101(), и я рассматриваю возможность переопределения методов в Formatter, чтобы сделать его защищенным для ненадежного ввода.
Ниже приведены риски, которые я вижу с помощью .format():
- Padding позволяет указать произвольные длины, поэтому '{: > 9999999999}'. format (..) может запустить сервер из памяти и быть DOS. Мне нужно отключить это.
- Формат позволяет вам получить доступ к полям внутри объектов, что полезно, но это жутко, что вы можете получить доступ к dunder-переменным и начать сверление в биты стандартной библиотеки. Там не сказано, где может быть getattr(), который имеет побочные эффекты или возвращает что-то секретное. Я бы выделил атрибут/индекс доступа, переопределив get_field().
- Естественно, мне нужно будет заполучить некоторые исключения.
Мои предположения:
- Ни один из традиционных эксплойтов строки формата C не применяется к Python, поскольку указание параметра - это ограниченный проверкой доступ к коллекции, а не прямой вывод из потока потока.
- Я использую веб-фреймворк каждой переменной, заменяемой шаблоном страницы, и до тех пор, пока она будет последней остановкой перед выходом, я не буду защищать от межсайтовых скриптовых атак, возникающих из-за отмены.
Каковы ваши мысли? Возможное? Невозможно? Просто неразумно?
Edit: Armin Ronacher описывает неприятную утечку информации, если вы не отфильтровываете доступ к переменной dunder, но, по-видимому, считаете, что формат защиты() возможен:
{local_foo.__init__.__globals__[secret_global]}
http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
(Лично я на самом деле не отправил маршрут ненадежного формата() в свой продукт, но обновляюсь для полноты)