python格式化字符串漏洞
参考:Python Web之flask session&格式化字符串漏洞-先知社区
在 python 中,提供了 4种 主要的格式化字符串方式,分别如下:
%操作符
%操作符 沿袭C语言中printf语句的风格。
1
2
3
|
>>> name = 'Bob'
>>> 'Hello, %s' % name
"Hello, Bob"
|
string.Template
使用标准库中的模板字符串类进行字符串格式化。
1
2
3
4
5
|
>>> name = 'Bob'
>>> from string import Template
>>> t = Template('Hey, $name!')
>>> t.substitute(name=name)
'Hey, Bob!'
|
python3后引入的新版格式化字符串写法,但是这种写法存在安全隐患。
1
2
3
4
5
|
>>> name , errno = 'Bob' , 50159747054
>>> 'Hello, {}'.format(name)
'Hello, Bob'
>>> 'Hey {name}, there is a 0x{errno:x} error!'.format(name=name, errno=errno)
'Hey Bob, there is a 0xbadc0ffee error!'
|
存在安全隐患的事例代码:
1
2
3
4
5
6
7
8
|
>>> config = {'SECRET_KEY': '12345'}
>>> class User(object):
... def __init__(self, name):
... self.name = name
...
>>> user = User('joe')
>>> '{0.__class__.__init__.__globals__[config]}'.format(user)
"{'SECRET_KEY': '12345'}"
|
如果用来格式化的字符串可以被控制,攻击者就可以通过注入特殊变量,带出敏感数据。
f-Strings
这是python3.6之后新增的一种格式化字符串方式,其功能十分强大,可以执行字符串中包含的python表达式
1
2
3
4
5
6
|
>>> a , b = 5 , 10
>>> f'Five plus ten is {a + b} and not {2 * (a + b)}.'
'Five plus ten is 15 and not 30.'
>>> f'{__import__("os").system("id")}'
uid=0(root) gid=0(root) groups=0(root)
'0'
|
更多参考这篇:Python 格式化字符串漏洞(Django为例) | 离别歌