TGTGInsighttelegram intelligenceLIVE / telegram public index
← Python Заметки
Python Заметки avatar

TGINSIGHT POST

Post #19

@pythonotes

Python Заметки

Views467Post view count
PostedJan 1601/16/2020, 09:00 AM
Post content

Post content

Почему нет функции, аналога для f-string? На самом деле, f-string можно представить в виде простой функции format() в которую вместе со стркой-шаблоном передаются словари locals() и globals(). Но так делать точно не стОит! И прежде всего, в целях безопасности. О чём это я? Допустим, у нас есть шаблон: template = 'Hello {username}!' И потом мы просто форматируем строку по этому шаблону псевдо-функцией fstring() (представим, что она существует) username = user.get_name() greeting = fstring(template) Выглядит всё логично, но тут есть скрытая угроза безопасности! Допустим, у нас некий веб сервис и мы предоставляем юзеру возможность сформировать себе любой шаблон какой ему нравится, после чего форматируем строку по аналогии с f-string. В чем же тут может быть опасность? А в том, что в отличие от простого метода строки format() этот способ имеет возможность вшить в шаблон любой экспрешн! То есть, мы позволяем юзеру написать любой код и самолично его выполняем на сервере! Если юзер действует по правилам, то напишет что-то вроде: "Hey what's up, {username}?)))" А если попадётся слишком догадливый, знающий о некомпетентности программиста и, допустим, что логика на Django+Python, то он может написать что-то такое: "{__import__('django.conf', fromlist=['conf']).settings.SECRET_KEY}" И алгоритм выдаст ему секретный ключ сайта! Можно и более кардинально: "{__import__('django.contrib.auth', fromlist=['auth']).get_user_model().objects.filter(email='[email protected]').update(is_superuser=True)}" Этот однострочный экспрешн делает юзера суперадмином! Теперь можно заходить на сайт как админ и делать там что хочешь))) Поэтому, только программист может формировать подобные строки. То есть нельзя в f-sting передать неизвестно что из переменной. Никогда не давайте юзерам слишком много свободы. Если требуется подобный функционал, лучше использовать простой метод format() или класс 'string.Template'. А ещё лучше, выдавать список готовых вариантов 🤓 PS. Для тех кто хочет поэкспериментировать с f-string функцией, можете попробовать этот вариант def fstring(fstring_text): return eval(f'f"{fstring_text}"', locals(), globals()) Пример: >>> template = 'Hello, {username}!' >>> username = 'Max' >>> fstring(template) Hello, Max! Теперь попробуйте придумать хитрые способы взлома) #tricks