Introduction to XSS (Cross Site Scripting)
XSS is one of the security issues that usually occurs when creating a website. XSS usually has security holes where people can deliberately enter parameters containing script or Javascript so that the website page can be rendered. The purpose of this XSS is to steal the browser cookies of users who are accessing the website and can cause user accounts to be taken over if we as website owners don’t handle it properly.
In contrast to programming like PHP, Golang interestingly solves this XSS problem automatically. Golang templates have their own Auto Escape feature which can detect data that needs to be displayed in the template and if it contains HTML tags or scripts it will automatically be escaped. This function can be seen here
- https://github.com/golang/go/blob/master/src/html/template/escape.go
- https://pkg.go.dev/text/template#HTMLEscape
How to Implement XSS
OK, let’s try to implement how Golang XSS works by first trying to create a file called post.html
in the templates/
folder and fill the file with the code below.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ .Title }}</title>
</head>
<body>
<h1>{{ .Title }}</h1>
{{ .Body }}
</body>
</html>
Then we create a handler for Auto Escape Golang Web like the code below.
func TemplateAutoEscapeHandler(w http.ResponseWriter, r *http.Request) {
myTemplates.ExecuteTemplate(w, "post.html", map[string]interface{}{
"Title": "Golang Tutorial Santekno Auto Escape",
"Body": "Selamat Belajar Golang Auto Escape Santekno",
})
}
After that, don’t forget to add the handler function to the router
in the main.go
file.
mux.HandleFunc("/template-auto-escape", TemplateAutoEscapeHandler)
And now build
, run
run the program and open the browser then the display will immediately appear according to the program we have created.
go build && ./learn-golang-web
And it will look like below.
Then we try injecting scripts or HTML tags into the handler. Will it appear and be rendered as plain text or will it be rendered as tags and scripts that can be read by the browser. We change our code like this.
func TemplateAutoEscapeHandler(w http.ResponseWriter, r *http.Request) {
myTemplates.ExecuteTemplate(w, "post.html", map[string]interface{}{
"Title": "Golang Tutorial Santekno Auto Escape",
"Body": "<p>Selamat Belajar Golang Auto Escape Santekno<script>alert('Halo Anda ke hack')</script></p>",
})
}
So what will happen? Just look at the display below {{ internal-img “web xss injected tags html and script” “tutorial-golang-web-xss-inject-tags.png” >}}
Can I turn off Auto Escape?
By default it will run automatically, but we can turn off this feature but we need to know that places can explicitly add date templates using HTML by using template.HTML
for HTML data and template.CSS
for CSS data and template .JS
is used for javascript data.
We will try to disable Auto Escape by creating a new handler function as below.
func TemplateDisabledAutoEscapeHandler(w http.ResponseWriter, r *http.Request) {
myTemplates.ExecuteTemplate(w, "post.html", map[string]interface{}{
"Title": "Golang Tutorial Santekno Auto Escape",
"Body": template.HTML("<p>Selamat Belajar Golang Auto Escape Santekno<script>alert('Halo Anda ke hack')</script></p>"),
})
}
Then add a handler to the mux router as below.
mux.HandleFunc("/template-disable-auto-escape", TemplateDisabledAutoEscapeHandler)
If we continue to run it, we will read the HTML tags sent in the browser like this.
And it will render the HTML like this.
XSS (Cross Site Scripting) Issues
If we turn off the auto escape feature, we can be sure that XSS problems will lurk on our website, so make sure that the data source we turn off auto escape from is safe from bad people who want to damage our website.
For example, if we receive params from outside and then we immediately assume it is HTML then it will be dangerous like the code below.
func TemplateXSSAttackHandler(w http.ResponseWriter, r *http.Request) {
myTemplates.ExecuteTemplate(w, "post.html", map[string]interface{}{
"Title": "Golang Tutorial Santekno Auto Escape",
"Body": template.HTML(r.URL.Query().Get("body")),
})
}
Then add the handler in mux
.
mux.HandleFunc("/template-xss-attack", TemplateXSSAttackHandler)
Run the program and access our website as below
localhost:8080/template-xss-attack?body=<script>alert('selamat anda ke hack')</script>
Then it will appear in the browser like this. This proves that our website is not safe because our website can be injected with javascript easily. So be careful when we turn off Auto Escape.