Go语言ssti漏洞
字数 1479 2025-08-22 12:23:30
Go语言SSTI漏洞深入分析与防御指南
1. SSTI漏洞概述
SSTI(Server-Side Template Injection)漏洞是由于不安全地处理模板引擎输入而导致的漏洞。攻击者可以利用SSTI注入恶意代码或表达式到模板引擎中,从而在服务器上执行任意代码或获取敏感数据。
2. Go语言中的模板引擎
Go语言内置了两个模板引擎:
2.1 text/template
- 用于生成纯文本输出
- 更灵活,但没有自动转义功能
- 容易导致SSTI漏洞
2.2 html/template
- 用于生成HTML输出
- 自带自动转义功能,较为安全
- 但仍需注意用户输入处理
其他流行模板引擎
- github.com/flosch/pongo2/v6:功能强大的模板引擎库,提供类似Django的模板语法
3. 典型漏洞环境分析
3.1 完全不安全的模板使用示例
- 存在XSS、SSTI导致的RCE漏洞风险
- 敏感信息泄露:通过
{{.Name}}等模板注入语句可获取User类属性
3.2 部分安全的模板使用示例
- 虽然正确使用了模板引擎,但由于模板渲染输入未正确过滤
- 仍存在XSS漏洞:输入
<script>alert('xss')</script>可触发XSS
4. 漏洞利用条件与方式
4.1 RCE漏洞触发条件
需要满足以下任意一条:
- 模板初始化时添加的parseFuncs存在触发RCE的方法
- 模板Execute时添加的data参数所属的类中存在触发RCE的方法
4.1.1 通过自定义parseFuncs实现RCE
- 在模板初始化时通过
Funcs方法添加自定义方法 - 调用方式:
{{exec "whoami"}}
4.1.2 通过data参数所属类方法实现RCE
- 当传入的data所属类中存在恶意方法时
- 调用方式:
{{.Gogo}} - 底层通过
/go/src/text/template/exec.go的evalField方法处理
4.2 内置方法调用
- text/template提供了一些内置方法
- 调用方式:
{{print "test"}}
5. 第三方模板引擎漏洞示例(pongo2/v6)
以CISCN2023的go_session赛题为例:
5.1 漏洞利用过程
- 分析
tpl.Execute(pongo2.Context{"c": c})代码 - 从传入的
gin.Context类中寻找可利用方法 - 利用
FormFile和SaveUploadedFile实现任意文件写入 - 使用
UserAgent()方法绕过字符过滤
5.2 最终payload
通过请求头中的User-Agent传参实现漏洞利用
6. 防御措施
6.1 基础防御
- 将
text/template替换为html/template - 对用户输入进行严格过滤和转义
6.2 高级防御
- 避免在模板中直接执行用户输入
- 限制自定义函数的功能
- 使用白名单验证模板变量
- 对敏感方法进行访问控制
6.3 针对不同场景的防御
- 对于纯文本输出:严格过滤所有动态内容
- 对于HTML输出:使用html/template并确保自动转义开启
7. 总结
Go语言中的SSTI漏洞主要源于:
- 使用不安全的模板引擎(text/template)
- 不当处理用户输入
- 暴露危险方法给模板环境
开发者应当:
- 优先使用html/template
- 严格审查传入模板的数据
- 避免在模板环境中暴露危险方法
- 定期进行安全审计和测试
通过理解模板引擎的工作原理和漏洞触发条件,可以更有效地预防和修复SSTI漏洞。