欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

服务端注入之Flask框架中服务端模板注入问题

来源:本站整理 作者:ForrestX386 时间:2017-06-05 TAG: 我要投稿

Flask 是python语言编写的轻量级的MVC (也可以称为MTV, T: Template)框架
具体详见
http://docs.jinkan.org/docs/flask/
对于Flask 框架本身,本文不做讨论。
本文主要通过几个例子,测试说明下Flask框架中服务端模板注入带来的安全隐患
0×01. 测试Code
 from flask import Flask, request, render_template_string, render_template
app = Flask(__name__)
@app.route('/hello-template-injection')
def hello_ssti():
person = {'name': "world", 'secret': "UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg=="}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = '''Hello %s!''' % person['name']
return render_template_string(template, person=person)
@app.route('/hello-xss')
def hello_xss():
name = "world"
template = 'hello.unsafe'# 'unsafe' file extension... totally legit.
if request.args.get('name'):
name = request.args.get('name')
return render_template(template, name=name)
@app.route('/html-attribute-xss')
def hello_hi():
template = '''No Injection Allowed!
Click here for a welcome message'''
name = "world"
if request.args.get('name'):
name = request.args.get('name')
return render_template_string(template, name=name)
####
# Private function if the user has local files.
###
def get_user_file(f_name):
with open(f_name) as f:
return f.readlines()
app.jinja_env.globals['get_user_file'] = get_user_file# Allows for use in Jinja2 templates
if __name__ == "__main__":
app.run(debug=True)
0×02. 模板字符串中字符串拼接或替换引发的安全隐患
我们看一下测试代码中的 hello_ssti函数
函数中模板内容
 template = '''Hello %s!''' % person['name']
就是简单的字符串替换,这会引发什么安全问题吗?
我们看例子:
运行后,浏览器访问: http://localhost:5000(Flask开发的程序,默认监听端口为5000)

OK, 打印Hello World。
但是,如果传入的name 参数值为恶意代码会怎么样?
引发敏感信息泄露
 http://localhost:5000/hello-template-injection?name=ForrestX386. {{person.secret}}

secret 值被泄露
原因:
我们知道Flask 中使用了Jinja2 作为模板渲染引擎,{{}}在Jinja2中作为变量包裹标识符,Jinja2在渲染的时候会把{{}}包裹的内容当做变量解析替换,如果传入的name=ForrestX386. {{person.secret}},那么在模板渲染的时候就会将{{}}替换成字典person中secret元素的值
**引发本地文件包含漏洞**
 http://localhost:5000/hello-template-injection?name=ForrestX386. {{get_user_file('E:\haha.txt')}}

E:\haha.txt 内容被泄露
原因:
同上,Jinja2在渲染模板的时候,将{{get_user_file(‘E:\haha.txt’)}}的内容替换成get_user_file(‘E:\haha.txt’)函数的返回值
如何解决上述问题:
将template = ”’Hello %s!”’ % person['name']
更改为template = ”’Hello {{person['name']}}!”’
这样以来,Jinja2在模板渲染的时候将person['name']的值替换掉{{person['name']}}, 而不会对person['name']内容进行二次渲染(这样即使`person['name']中含有{{}}也不会进行渲染,而只是把它当做普通字符串)
0×03. render_template_string 的安全隐患
我们知道Flask render_template函数在模板渲染(使用Jinja2模板引擎)的时候,会自动对模板(常见的模板后缀才进行自动HTML转码,比如.html,.htm等,不常见的模板后缀是不会进行HTML自动编码的,下面会介绍到)内容进行HTML实体编码,从而避免XSS漏洞的发生,但是Flask中的render_template_string 函数却不会对要渲染的模板字符串进行自动HTML实体编码,存在XSS安全隐患
下面看一个例子
引发XSS
http://localhost:5000/hello-template-injection?name=ForrestX386. alert(“welcome to visit ForrestX386.github.io.”)

确实发生了XSS

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载