go_ssti风险
字数 1163 2025-08-22 12:22:37

Go语言中的SSTI(服务器端模板注入)风险详解

1. SSTI基础概念

SSTI(Server-Side Template Injection,服务端模板注入)是一种Web应用漏洞,发生在应用程序使用不安全的模板引擎进行服务器端模板渲染时。攻击者通过在用户输入中注入恶意模板代码,服务器在渲染模板时执行了这些代码,从而导致执行任意代码、窃取数据或执行其他恶意操作。

常见易受攻击的模板引擎:

  • Jinja2 (Python)
  • Thymeleaf (Java)
  • Smarty (PHP)
  • Go的text/template (不安全使用情况下)

2. SSTI攻击流程

  1. 发现模板渲染位置:通过各种输入字段尝试注入模板表达式,观察输出变化
  2. 模板注入:注入模板引擎的特殊语法(如Jinja2中的{{ 7*7 }})
  3. 代码执行:构造恶意模板表达式执行任意代码或获取敏感数据

3. Go语言中的SSTI风险

Go标准库提供两种模板引擎:

  • html/template:为防范XSS设计,默认对HTML自动转义,较为安全
  • text/template:没有自动转义功能,不当使用可能导致SSTI或其他代码注入风险

3.1 基础示例

package main

import (
    "os"
    "text/template"
)

func main() {
    tmpl, err := template.New("").Parse("你好, {{.}}")
    if err != nil {
        panic(err)
    }
    err = tmpl.Execute(os.Stdout, "冰镇")
    if err != nil {
        panic(err)
    }
}

输出:你好, 冰镇

4. 漏洞靶场示例

4.1 基础靶场代码

package main

import (
    "fmt"
    "net/http"
    "text/template"
)

type User struct {
    Id     int
    Name   string
    Passwd string
}

func sstiHandler(w http.ResponseWriter, r *http.Request) {
    userInput := r.URL.Query().Get("input")
    user := &User{1, "admin", "laotie233"}
    
    tmpl, err := template.New("ssti").Parse(userInput)
    if err != nil {
        http.Error(w, "Error parsing template", http.StatusInternalServerError)
        return
    }
    
    err = tmpl.Execute(w, user)
    if err != nil {
        http.Error(w, "Error executing template", http.StatusInternalServerError)
        return
    }
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
    homeHTML := `<!DOCTYPE html>
    <html>
    <head><title>SSTI Vulnerable Web App</title></head>
    <body>
        <h1>SSTI Vulnerable Web App</h1>
        <form action="/ssti" method="get">
            <input type="text" name="input" placeholder="Enter your template">
            <button type="submit">Submit</button>
        </form>
    </body>
    </html>`
    fmt.Fprint(w, homeHTML)
}

func main() {
    http.HandleFunc("/", homeHandler)
    http.HandleFunc("/ssti", sstiHandler)
    fmt.Println("Server is running on http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

4.2 攻击Payload示例

  1. 敏感信息泄露

    • 获取密码:{{.Passwd}}
    • 获取全部用户信息:{{.}}
  2. XSS攻击

    • <script>alert('xss')</script>

5. 高危功能扩展示例

5.1 扩展靶场代码(添加危险函数)

package main

import (
    "fmt"
    "net/http"
    "os"
    "os/exec"
    "text/template"
)

// ... User结构体和homeHandler保持不变 ...

func sstiHandler(w http.ResponseWriter, r *http.Request) {
    userInput := r.URL.Query().Get("input")
    user := &User{1, "admin", "laotie233"}
    
    tmpl, err := template.New("ssti").Funcs(template.FuncMap{
        "exec": func(command string) string {
            out, err := exec.Command("sh", "-c", command).Output()
            if err != nil {
                return err.Error()
            }
            return string(out)
        },
        "readFile": func(filePath string) string {
            content, err := os.ReadFile(filePath)
            if err != nil {
                return err.Error()
            }
            return string(content)
        },
    }).Parse(userInput)
    
    // ... 错误处理和模板执行保持不变 ...
}

5.2 高危Payload示例

  1. 命令执行

    • {{ exec "ls" }}
    • {{ exec "whoami" }}
    • {{ exec "cat /etc/passwd" }}
  2. 文件读取

    • {{ readFile "/etc/passwd" }}
    • {{ readFile "/etc/shadow" }}

6. 防御措施

  1. 避免直接使用用户输入进行模板渲染

    • 不要将用户输入直接作为模板内容
  2. 严格过滤用户输入

    • 使用白名单限制允许的输入内容
    • 对特殊字符进行转义处理
  3. 选择安全的模板引擎

    • 优先使用html/template而非text/template
    • 启用模板引擎的安全模式或沙盒功能
  4. 安全审计和测试

    • 静态代码分析
    • 渗透测试
    • 自动化漏洞扫描
  5. 最小权限原则

    • 限制模板中可执行的函数和操作
    • 避免在模板中暴露敏感信息

7. 总结

Go语言中的SSTI风险主要来自于不安全的text/template使用,虽然其杀伤力可能不如Jinja2等模板引擎,但仍然可能导致敏感信息泄露、XSS攻击甚至远程代码执行。开发者应当充分了解模板注入原理,采取适当的防御措施,确保应用程序的安全性。

Go语言中的SSTI(服务器端模板注入)风险详解 1. SSTI基础概念 SSTI(Server-Side Template Injection,服务端模板注入)是一种Web应用漏洞,发生在应用程序使用不安全的模板引擎进行服务器端模板渲染时。攻击者通过在用户输入中注入恶意模板代码,服务器在渲染模板时执行了这些代码,从而导致执行任意代码、窃取数据或执行其他恶意操作。 常见易受攻击的模板引擎: Jinja2 (Python) Thymeleaf (Java) Smarty (PHP) Go的text/template (不安全使用情况下) 2. SSTI攻击流程 发现模板渲染位置 :通过各种输入字段尝试注入模板表达式,观察输出变化 模板注入 :注入模板引擎的特殊语法(如Jinja2中的 {{ 7*7 }} ) 代码执行 :构造恶意模板表达式执行任意代码或获取敏感数据 3. Go语言中的SSTI风险 Go标准库提供两种模板引擎: html/template :为防范XSS设计,默认对HTML自动转义,较为安全 text/template :没有自动转义功能,不当使用可能导致SSTI或其他代码注入风险 3.1 基础示例 输出: 你好, 冰镇 4. 漏洞靶场示例 4.1 基础靶场代码 4.2 攻击Payload示例 敏感信息泄露 : 获取密码: {{.Passwd}} 获取全部用户信息: {{.}} XSS攻击 : <script>alert('xss')</script> 5. 高危功能扩展示例 5.1 扩展靶场代码(添加危险函数) 5.2 高危Payload示例 命令执行 : {{ exec "ls" }} {{ exec "whoami" }} {{ exec "cat /etc/passwd" }} 文件读取 : {{ readFile "/etc/passwd" }} {{ readFile "/etc/shadow" }} 6. 防御措施 避免直接使用用户输入进行模板渲染 不要将用户输入直接作为模板内容 严格过滤用户输入 使用白名单限制允许的输入内容 对特殊字符进行转义处理 选择安全的模板引擎 优先使用 html/template 而非 text/template 启用模板引擎的安全模式或沙盒功能 安全审计和测试 静态代码分析 渗透测试 自动化漏洞扫描 最小权限原则 限制模板中可执行的函数和操作 避免在模板中暴露敏感信息 7. 总结 Go语言中的SSTI风险主要来自于不安全的 text/template 使用,虽然其杀伤力可能不如Jinja2等模板引擎,但仍然可能导致敏感信息泄露、XSS攻击甚至远程代码执行。开发者应当充分了解模板注入原理,采取适当的防御措施,确保应用程序的安全性。