前言
作为强类型的静态语言,golang的安全属性从编译过程就能够避免大多数安全问题,一般来说也唯有依赖库和开发者自己所编写的操作CVE,才有可能形成CVE利用点,在本文,主要学习探讨一下golang的一些ssti模板注入问题。
GO模板引擎
Go 提供了两个模板包。一个是 text/template
,另一个是html/template
。text/template对 XSS 或任何类型的 HTML 编码都没有保护,因此该模板并不适合构建 Web 应用程序,而html/template与text/template基本相同,但增加了HTML编码等安全保护,更加适用于构建web应用程序。
template简介
template之所以称作为模板的原因就是其由静态内容和动态内容所组成,可以根据动态内容的变化而生成不同的内容信息交由客户端,以下即一个简单例子
模板内容 Hello, {
{.Name}} Welcome to go web programming…期待输出 Hello, liumiaocn Welcome to go web programming…
而作为go所提供的模板包,text/template和html/template的主要区别就在于对于特殊字符的转义与转义函数的不同,但其原理基本一致,均是动静态内容结合,以下是两种模板的简单演示。
text/template
package mainimport ("net/http""text/template")type User struct {ID intName stringEmailstringPassword string}func StringTpl2Exam(w http.ResponseWriter, r *http.Request) {user := &User{1,"John", "test@example.com", "test123"}r.ParseForm()tpl := `<h1>Hi, {
{ .Name }}</h1><br>Your Email is {
{ .Email }}`data := map[string]string{"Name":user.Name,"Email": user.Email,}html := template.Must(template.New("login").Parse(tpl))html.Execute(w, data)}func main() {server := http.Server{Addr: "127.0.0.1:8888",}http.HandleFunc("/string", StringTpl2Exam)server.ListenAndServe()}
struct是定义了的一个结构体,在go中,我们是通过结构体来类比一个对象,因此他的字段就是一个对象的属性,在该实例中,我们所期待的输出内容为下
模板内容 <h1>Hi, {
{ .Name }}</h1><br>Your Email is {
{ .Email }}期待输出 <h1>Hi, John</h1><br>Your Email is test@example.com
可以看得出来,当传入参数可控时,就会经过动态内容生成不同的内容,而我们又可以知道,go模板是提供字符串打印功能的,我们就有机会实现xss。
package mainimport ("net/http""text/template")type User struct {ID intName stringEmailstringPassword string}func StringTpl2Exam(w http.ResponseWriter, r *http.Request) {user := &User{1,"John", "test@example.com", "test123"}r.ParseForm()tpl := `<h1>Hi, {
{"<script>alert(/xss/)</script>"}}</h1><br>Your Email is {
{ .Email }}`data := map[string]string{"Name":user.Name,"Email": user.Email,}html := template.Must(template.New("login").Parse(tpl))html.Execute(w, data)}func main() {server := http.Server{Addr: "127.0.0.1:8888",}http.HandleFunc("/string", StringTpl2Exam)server.ListenAndServe()}
模板内容 <h1>Hi, {
{"<script>alert(/xss/)</script>"}}</h1><br>Your Email is {
{ .Email }}期待输出 <h1>Hi, {
{"<script>alert(/xss/)</script>"}}</h1><br>Your Email is test@example.com实际输出 弹出/xss/
这里就是text/template和html/template的最大不同了。
html/template
同样的例子,但是我们把导入的模板包变成html/template
package mainimport