【SSTL技巧拓展】————2、服务端注入之Flask框架中服务端模板注入问题

本文探讨Flask框架中模板使用的安全问题,包括服务端模板注入、XSS漏洞、不常见模板后缀及HTML标签属性绕过的风险,并提供防范措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

严正声明:本文仅限于技术讨论与学术学习研究之用,严禁用于其他用途(特别是非法用途,比如非授权攻击之类),否则自行承担后果,一切与作者和平台无关,如有发现不妥之处,请及时联系作者和平台。

0×00. 前言 

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 = '''<h2>Hello %s!</h2>''' % 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 = '''<title>No Injection Allowed!</title>
<a href={{ url_for('hello_xss')}}?name={{ name |e}}>
Click here for a welcome message</a>'''
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 = '''<h2>Hello %s!</h2>''' % 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 = ”’<h2>Hello %s!</h2>”’ % person['name']

更改为template = ”’<h2>Hello {{person['name']}}!</h2>”’

这样以来,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. <script>alert(“welcome to visit ForrestX386.github.io.”)</script>

确实发生了XSS弹窗,说明render_template_string 函数没有进行自动HTML实体编码

注: 如果你在测试过程中使用的是chrome浏览器,且没有弹框,请把chrome XSS 过滤器给关闭,你可以这样关闭chrome xss 过滤器,在目标后面加上`–args –disable-xss-auditor `

确定,重启chrome,就可以了

如何解决上述问题

我们可以在输出的内容后面加上`| e`,这样就要求Jinja2模板引擎 将输出内容HTML实体编码后再输出给用户

template = '<h2>Hello {{ person['name'] | e }}!</h2>'

恩,这样就不会有XSS 漏洞了

0×04. 使用不常见的模板后缀引发的安全隐患

我们看一下测试代码中的hello_xss 方法,其中模板为`template = ‘hello.unsafe’`, 后缀unsafe 不是Jinja2模板引擎支持的自动HTML编码的模板后缀,如果编写模板内容的时候不够细心或者考虑不周全,则可能引发XSS漏洞。 看下面的例子

如果hello.unsafe模板内容是这样的:

 
{% autoescape true %}
<h2>Good</h2>
<p>
Hello {{ name }}! I don't trust your input. I escaped it, just in case.
</p>
{% endautoescape %}
<h2>Bad</h2>
<p>
I trust all data! How are you {{ name }}?
</p>

区块Good 使用Jinja2中autoescape方法,而区块Bad 没有使用,我们访问下面的url看看会发生什么

http://localhost:5000/hello-xss?name=ForrestX386.<script>document.title="xss";</script>

是的,使用autoescape方法的区块没有XSS漏洞(autoescape函数会自动将所包裹区块自动HTML实体编码),而没有使用autoescape方法的区块(Bad区块)发生XSS漏洞,说明render_template是不会对不支持自动HTML实体编码的模板后缀进行自动HTML实体编码

所以当使用render_template渲染Jinja2模板引擎不支持自动HTML实体编码的模板后缀的时候,请小心仔细一些,在有用户输入的的地方使用autoescape方法

如何解决上述问题

除了使用autoescape方法,我们还可以在要渲染的内容后面加上` |e `进行HTML实体编码

比如将Bad 区块内容更改为

<h2>Bad</h2>
<p>
I trust all data! How are you {{ name |e }}?
</p>

这样就不会有XSS漏洞了

0×05. 利用模板中html标签属性字段绕过xss过滤

我们在0×03节谈到了render_template_string 不会对要渲染的字符串进行自动HTML实体编码转换,但是可以使用|e 对输出内容进行HTM实体编码转换,那么使用`|e`一定安全吗? 那倒不一定,不信看看下面的测试:

我们看一下测试代码中的hello_hi方法

@app.route('/html-attribute-xss')
def hello_hi():
template = '''<title>No Injection Allowed!</title>
<a href={{ url_for('hello_xss')}}?name={{ name |e}}>
Click here for a welcome message</a>'''
name = "world"
if request.args.get('name'):
name = request.args.get('name')
return render_template_string(template, name=name)

name 虽然使用|e 进行html实体转义 ,但我们可以通过下面的方式进行绕过,浏览器访问:

http://localhost:5000/html-attribute-xss?name=test οnmοuseοver=document.title="xss-again"

打开的界面是这样的:

当我们把鼠标放在超链接上的时候

注意到没有 title 变成了xss-again,说明xss注入成功
原因:
name 参数传入的值为test οnmοuseοver=document.title=”xss-again”,替换之后变成

<a href={{ url_for('hello_xss')}}?name=test οnmοuseοver=document.title="xss-again" >

因为注入的name参数值渲染后出现在了HTML标签的属性值中,而|e 是不会对属性值进行HTML转义过滤的

如何解决:

只要使用单引号或者双引号将href的值括起来就可以了

<a href="{{ url_for('hello_xss')}}?name={{ name |e}}">

0×06. 总结

通过上面的例子,我们总结了再Flask框架中使用模板可能带来的一些安全隐患以及对应的解决方法,让我们了解了使用模板中一些tips。总之,我们在使用Flask开发的时候,一定要谨记:用户的任何输入都是不可信的,要在输入和输出端都做好过滤

Origin Refer:https://nvisium.com/blog/2015/12/07/injecting-flask/

 

### SSTL2_DCI 和 LVCmos12 的技术规范与差异 #### 1. **SSTL2_DCI (Stub Series Terminated Logic)** SSTL 是一种用于高速数据传输的标准接口逻辑电平,广泛应用于 DDR SDRAM 接口。SSTL2_DCI 特指第二代 SSTL 配置下的驱动器特性。 - **电压范围**: SSTL2 使用的核心电源电压通常为 2.5V[^1],而 I/O 电压则维持在约 2.5V ± 0.2V 范围内。 - **信号摆幅**: SSTL2_DCI 提供较低的信号摆幅以减少电磁干扰(EMI),其典型高电平约为 \( V_{DDQ} - 0.4 \) V,低电平约为 \( V_{SS} + 0.4 \) V[^2]。 - **终端匹配**: SSTL2_DCI 强调通过串联电阻实现终端匹配,从而降低反射效应并提高信号完整性。 - **应用场景**: 主要适用于内存控制器到 DRAM 模块之间的通信链路。 #### 2. **LVCMOS12 (Low Voltage Complementary Metal-Oxide-Semiconductor)** LVCMOS 是 CMOS 技术的一种变体,支持更低的工作电压,适合低功耗设计需求。 - **电压范围**: LVCMOS12 表明该标准运行于 1.2V 核心供电下,输入/输出兼容性也基于此电压水平[^3]。 - **信号摆幅**: 它提供完整的轨到轨(rail-to-rail)信号幅度,即从接近 GND 到近似 \( V_{CCIO} \)[^4]。 - **负载能力**: 对比其他低压标准,LVCMOS 更能承受较大的容性负载而不显著影响性能。 - **应用领域**: 常见于微处理器、FPGA 及 ASIC 设计中的内部外设互联部分。 #### 3. **主要区别对比** | 参数 | SSTL2_DCI | LVCMOS12 | |-------------------|------------------------------------|----------------------------------| | **核心工作电压** | ~2.5V | ~1.2V | | **信号振幅控制** | 减弱型 | 全轨至轨 | | **抗噪能力** | 较强 | 中等 | | **功率消耗** | 相对较高 | 显著偏低 | 值得注意的是,在混合使用这两种不同电气特性的组件时需特别小心处理电平转换问题以免损坏设备或者引起功能紊乱[^5]。 ```python # 示例 Python 代码展示如何设置 FPGA IO Standard def configure_fpga_io(pin_name, io_standard): if io_standard == 'SSTL2_DCI': set_voltage(2.5) elif io_standard == 'LVCMOS12': set_voltage(1.2) apply_config(pin_name) configure_fpga_io('PIN_A', 'SSTL2_DCI') configure_fpga_io('PIN_B', 'LVCMOS12') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值