基于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()示例中,漏洞成因在于:

  1. 使用%s动态替换字符串
  2. 用户输入code完全可控
  3. 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. 防御措施

  1. 避免直接渲染用户输入:

    • 不要使用render_template_string()渲染用户可控的输入
    • 如果必须使用,应对输入进行严格过滤
  2. 使用安全的模板渲染方式:

    • 优先使用render_template()渲染预定义的模板
    • 在模板中明确指定变量来源
  3. 输入过滤:

    • 过滤或转义特殊字符
    • 使用白名单验证输入内容

10. 后续学习方向

  1. Jinja2模板语法深入学习
  2. SSTI漏洞利用技术(如命令执行、文件读取等)
  3. Flask安全配置最佳实践
  4. 其他模板引擎的SSTI漏洞研究

通过掌握这些基础知识,您已经具备了Flask SSTI漏洞的基本理解和初步测试能力。后续可以深入研究漏洞利用技术和防御方法。

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环境的步骤: 4. Flask 路由 基本路由 访问 http://127.0.0.1:5000/ 将显示"Hello 2333 !" 带参数的路由 访问 http://127.0.0.1:5000/hello/Sviivya0 将显示"Hello Sviivya0" 参数类型转换 | 转换类型 | 作用 | |---------|-------------------| | int | 整型 | | float | 浮点型 | | path | 可以有斜杠的字符型 | 多路由规则 路由绑定IP和端口 debug=True 启用调试模式,修改代码后无需重启服务。 5. Flask 渲染方法 Flask有两种主要的渲染方法: 1. render_ template() 渲染指定模板文件,自动在 templates 文件夹中查找对应的HTML文件。 2. render_ template_ string() 渲染字符串模板,这是SSTI漏洞的主要来源。 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漏洞的基本理解和初步测试能力。后续可以深入研究漏洞利用技术和防御方法。