This article is mainly about the Python template engine injection problem analysis, and how to prevent and need to pay attention to the place, the need for small partners can refer to the following
A loophole in the past few years is the injection of a template engine like JINJIA2, which returns 2 by injecting some specific instruction formats of the template engine, such as {{+ +}}. The actual similar problem exists in the Python native string, especially after the addition of the Python 3.6 F string, although the use is not yet clear, but should be noticed.
The most primitive%
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 real password can be obtained.
Format method Related
Https://docs.python.org/3/library/functions.html#format
In addition to the above payload rewritten to print ("Password" + passwd + "is wrong for user {user}"). Format (**userdata), you can also
>>> import os>>> ' {0.system} '. Format (OS) ' <built-in function system> '
Replaces 0 with the parameter in format before continuing to get the related property.
But it seems that you can only get properties, can't execute methods? But you can also get some sensitive information.
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 = Messagedef format_event (format_string, event): return format _string.format (event=event)
If format_string is {Event.__init__.__globals__[config][secret_key]}, you can disclose 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 get the current context variable.
Https://docs.python.org/3/reference/lexical_analysis.html#f-strings
>>> a = "Hello" >>> B = f "{A} World" >>> B ' Hello World '
And not only is it restricted to attributes, the code can be executed.
>>> import os>>> F "{os.system (' ls ')}" bin etc lib media proc run SRV tmp Vardev 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 to an F string, which means that the user will probably not be able to control an F string, may not be available, and need to continue checking.