当前位置:   article > 正文

常见的web攻击方式之服务器端模板注入

常见的web攻击方式之服务器端模板注入

服务器模板注入 (SSTI ) 是一种利用公共 Web 框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点。SSTI 攻击可以用来找出 Web 应用程序的内容结构。下面举一个例子:
使用 Flask 构建一个基本的 Web 应用程序:

from flask import Flask
from flask import request, render_template_string, render_template

app = Flask(__name__)

@app.route('/login')
def hello_ssti():
    person = {
        'name': 'hello',
        'secret': '7d793037a0760186574b0282f2f435e7'
    }
    if request.args.get('name'):
        person['name'] = request.args.get('name')
    
    template = '<h2>Hello %s!</h2>' % person['name']

    return render_template_string(template, person=person)

if __name__ == "__main__":
    app.run(debug=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

运行上面这段代码,并在浏览器中访问 http://127.0.0.1:5000/login,显示的结果为:
在这里插入图片描述
然后我们尝试一些良性的输入,访问 http://127.0.0.1:5000/login?name=bob,结果为:
在这里插入图片描述
下面演示一些攻击者的输入,比如访问 http://127.0.0.1:5000/login?name=bob{{person.secret}},你会发现页面中除了显示了 Hello bob!之外,连同秘钥也一起被显示了。
在这里插入图片描述
由于在模板中使用的是 % 字符串模板,所以它对任何传递给 python 表达式的内容进行了求值。在 Flask 模板语言中,我们传递了 {{ person.secret }},它对字典 person 中保密的键值进行了求值,这泄露了应用程序的秘钥。
我们还可以执行更强大的攻击,访问 http://127.0.0.1:5000/login?name={% for item in person %}<p>{{ item, person[item] }}</p>{% endfor %},你会发现整个 person 字典中的内容全被显示在页面中了。
在这里插入图片描述
即使攻击者想要获取服务器端敏感的配置参数,也可以通过 {{ config }} 的名称采纳数来获取,访问 http://127.0.0.1:5000/login?name={{%20config%20}},你会发现服务器的配置显示在页面中了。
在这里插入图片描述
那么如何避免敏感信息泄露呢,在这个情况下,解决的方法是使用模板中我们需要的特定变量,而不是直接使用 %s。
比如我们将 flask 代码改为:

from flask import Flask
from flask import request, render_template_string, render_template

app = Flask(__name__)

@app.route('/login')
def hello_ssti():
    person = {
        'name': 'world',
        'secret': '7d793037a0760186574b0282f2f435e7'
    }
    if request.args.get('name'):
        person['name'] = request.args.get('name')
    
    template = '<h2>Hello {{ person.name }}!</h2>'

    return render_template_string(template, person=person)

if __name__ == "__main__":
    app.run(debug=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

然后我们在尝试访问 http://127.0.0.1:5000/login?name={{%20config%20}},你会发现显示的结果只是字符串 {{ config }},而没有服务器的敏感信息了。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/946815
推荐阅读
相关标签
  

闽ICP备14008679号