Python 模板注入与字符串格式化安全风险解析
本文深入分析 Python 中模板引擎及字符串格式化带来的安全风险。从 Jinja2 注入到原生 %s 格式化,再到 format 方法及 Python 3.6 引入的 f-string,详细探讨攻击者如何利用这些特性获取敏感信息或执行代码。尽管 f-string 的用户可控性存在争议,但其潜在的代码执行能力仍需高度警惕。
近年来,Jinja2 等模板引擎注入漏洞备受关注。攻击者通过注入特定模板指令(如 {{1+1}})并观察返回值(如 2)来验证漏洞存在。实际上,类似风险在 Python 原生字符串处理中同样存在,尤其是 Python 3.6 引入 f-string 后,尽管其利用路径尚不明确,但潜在的安全隐患值得开发者高度重视。
最原始的 % 格式化方式
userdata = {"user" : "jdoe", "password" : "secret" }
passwd = raw_input("Password: ")
if passwd != userdata["password"]:
print ("Password " + passwd + " is wrong for user %(user)s") % userdata
若用户输入 %(password)s,攻击者即可通过格式化操作获取用户的真实密码。
format 方法相关风险
https://docs.python.org/3/library/functions.html#format
除了将 payload 改写为 print ("Password " + passwd + " is wrong for user {user}").format(**userdata) 外,还存在其他利用方式。
>>> import os
>>> '{0.system}'.format(os)
'<built-in function system>'
系统会先将 0 替换为 format 中的参数,随后继续尝试获取相关属性。
虽然似乎仅能获取属性而无法直接执行方法,但这已足以泄露部分敏感信息。
参考案例: http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
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)
若 format_string 构造为 {event.__init__.__globals__[CONFIG][SECRET_KEY]},即可成功泄露敏感配置信息。
Python 3.6 中的 f-string
这种字符串类型功能强大,类似于 JavaScript ES6 中的模板字符串,具备获取当前上下文变量的能力。
https://docs.python.org/3/reference/lexical_analysis.html#f-strings
>>> a = "Hello"
>>> b = f"{a} World"
>>> b
'Hello World'
更重要的是,f-string 不再局限于属性访问,甚至支持代码执行。
>>> 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'
然而,目前似乎没有将普通字符串直接转换为 f-string 的方法,这意味着用户可能无法直接控制一个 f-string,从而限制了利用可能性,具体细节仍需进一步验证。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









