This article mainly talks about the analysis of the injection problem of the Python template engine, as well as how to prevent it and what needs to be paid attention to. Friends in need can refer to it
One of the more popular vulnerabilities in recent years is In the injection of template engines such as jinjia2, we know that the vulnerability exists by injecting some specific instruction formats of the template engine, such as {{1+1}} and returning 2. In fact, similar problems exist in Python native strings, especially after the new f string was added in Python 3.6. Although the utilization is not clear yet, it should be noted.
The most original%
userdata = {"user" : "jdoe", "password" : "secret" } passwd = raw_input("Password: ") if passwd != userdata["password"]: print ("Password " + passwd + " is wrong for user %(user)s") % userdata
If the user enters %(password)s, then the user’s true identity can be obtained Password.
format method related
https://docs.python.org/3/library/functions.html#format
In addition to rewriting the above payload as print ("Password " + passwd + " is wrong for user {user}").format(**userdata), you can also
>>> import os >>> '{0.system}'.format(os) '<built-in function system>'
will first replace 0 with the parameters in format, and then continue to obtain related attributes.
But it seems that I can only get properties, but not execute methods? But some sensitive information can also be obtained.
Example: http://www.php.cn/
CONFIG = { 'SECRET_KEY': 'super secret key' } class Event(object): def __init__(self, id, level, message): self.id = id self.level = level self.message = message def format_event(format_string, event): return format_string.format(event=event)
If format_string is {event.__init__.__globals__[CONFIG][ SECRET_KEY]} can leak sensitive information.
The f string in Python 3.6
This string is very powerful, similar to the template string in Javascript ES6, with the ability to obtain variables in the current context .
https://docs.python.org/3/reference/lexical_analysis.html#f-strings
>>> a = "Hello" >>> b = f"{a} World" >>> b 'Hello World'
And it is not only limited to attributes, the code can be executed.
>>> import os >>> f"{os.system('ls')}" bin etc lib media proc run srv tmp var dev home linuxrc mnt root sbin sys usr '0' >>> f"{(lambda x: x - 10)(100)}" '90'
But there seems to be no way to convert an ordinary string into an f-string, which means that the user may not be able to control an f-string, and may not be able to To take advantage, you need to continue to check.
For more articles related to Python template engine injection problem analysis, please pay attention to the PHP Chinese website!