基于Flask的SSTI入门~
字数 1716 2025-08-06 08:35:16
Flask SSTI (服务器端模板注入) 入门指南
1. SSTI 概述
SSTI (Server-Side Template Injection) 是一种服务器端模板注入漏洞,当用户输入的数据没有被合理处理、控制和过滤时,可能插入程序从而改变程序的执行逻辑,导致敏感信息泄露、代码执行甚至获取服务器权限。
在Python中,主要的SSTI框架包括:
- Jinja2 (Flask默认使用)
- Mako
- Tornado
- Django
2. Flask 基础语法
Flask使用Jinja2作为模板引擎,其基本语法包括:
{{ ... }}:装载变量,渲染时会被同名参数的值替换{% ... %}:装载控制语句(如if条件判断){# ... #}:装载注释,渲染时会被忽略- 过滤器:对HTML中传入的变量进行处理,格式为
{{变量|过滤器}},如:upper():转换为大写lower():转换为小写length():获取长度
3. Flask 环境搭建
使用Pycharm搭建Flask环境的步骤:
pip install virtualenv # 安装虚拟环境
python -m virtualenv env # 创建虚拟环境
pip install flask # 安装Flask
4. Flask 路由
基本路由
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello 2333!'
if __name__ == '__main__':
app.run()
访问http://127.0.0.1:5000/将显示"Hello 2333!"
带参数的路由
@app.route('/hello/<username>')
def hello_user(username):
return f'Hello {username}'
访问http://127.0.0.1:5000/hello/Sviivya0将显示"Hello Sviivya0"
参数类型转换
| 转换类型 | 作用 |
|---|---|
| int | 整型 |
| float | 浮点型 |
| path | 可以有斜杠的字符型 |
多路由规则
@app.route('/')
@app.route('/hello')
def hello():
return 'Hello World'
路由绑定IP和端口
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
debug=True启用调试模式,修改代码后无需重启服务。
5. Flask 渲染方法
Flask有两种主要的渲染方法:
1. render_template()
渲染指定模板文件,自动在templates文件夹中查找对应的HTML文件。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
context = {
'username': 'ssss',
'gender': 'yyyy'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
2. render_template_string()
渲染字符串模板,这是SSTI漏洞的主要来源。
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/test/')
def test():
code = request.args.get('id')
html = '''
<h3>%s</h3>
''' % (code)
return render_template_string(html)
if __name__ == '__main__':
app.debug = True
app.run()
6. SSTI 漏洞成因
在上述render_template_string()示例中,漏洞成因在于:
- 使用
%s动态替换字符串 - 用户输入
code完全可控 - Flask基于Jinja2模板引擎,会解析模板语法
测试方法:
- 访问
http://127.0.0.1:5000/test/?id={{8*8}},页面将显示"64",证明表达式被执行 - 也可以进行XSS测试:
http://127.0.0.1:5000/test/?id=<script>alert(1)</script>
7. Flask 请求参数获取
Flask通过request对象获取请求参数:
request.args:获取GET请求参数(URL中的参数)request.form:获取POST请求参数request.values:获取所有参数(GET和POST)
8. Python sys.argv[] 用法
sys.argv[]是从外部获取参数的桥梁,它是一个列表:
sys.argv[0]:程序本身sys.argv[1]:第一个参数- 以此类推
9. 防御措施
-
避免直接渲染用户输入:
- 不要使用
render_template_string()渲染用户可控的输入 - 如果必须使用,应对输入进行严格过滤
- 不要使用
-
使用安全的模板渲染方式:
- 优先使用
render_template()渲染预定义的模板 - 在模板中明确指定变量来源
- 优先使用
-
输入过滤:
- 过滤或转义特殊字符
- 使用白名单验证输入内容
10. 后续学习方向
- Jinja2模板语法深入学习
- SSTI漏洞利用技术(如命令执行、文件读取等)
- Flask安全配置最佳实践
- 其他模板引擎的SSTI漏洞研究
通过掌握这些基础知识,您已经具备了Flask SSTI漏洞的基本理解和初步测试能力。后续可以深入研究漏洞利用技术和防御方法。