- Published on
XSS - Cross Site Scripting Vulnerability
- Authors
- Name
- Moch Lutfi
- @kaptenupi
Many developers are aware of Cross Site Scripting (XSS), but few have attempted to use it to exploit a web application. Despite being listed as a top 10 security risk by OWASP since 2003, XSS remains a prevalent vulnerability. The OWASP Top 10 security risks version from 2013 provides a comprehensive overview of XSS, including information on attack vectors, vulnerabilities, and the technical and business impacts of a successful XSS attack.
In short
You are vulnerable if you do not ensure that all user supplied input is properly escaped, or you do not verify it to be safe via server-side input validation, before including that input in the output page. source
_14package main_14_14import (_14 "io"_14 "net/http"_14)_14_14func handler(w http.ResponseWriter, r *http.Request) {_14 io.WriteString(w, r.URL.Query().Get("param1"))_14}_14func main() {_14 http.HandleFunc("/", handler)_14 http.ListenAndServe(":8080", nil)_14}
As Content-Type HTTP response header is not explicitly defined, Go http.DetectContentType
default value will be used, which follows the WhatWG spec. So, the Content-Type HTTP response header will depends on param1
values. If the params1
contains plain text it will return text/plain
but if user pass it using html markup it will automatically return text/html
.
Here the proove:
_15❯ curl -i http://localhost:8000/\?param1\="<script>alert(1)</script>"_15HTTP/1.1 200 OK_15Date: Tue, 24 Jan 2023 07:48:56 GMT_15Content-Length: 25_15Content-Type: text/html; charset=utf-8_15_15<script>alert(1)</script>% _15_15❯ curl -i http://localhost:8000/\?param1\=test _15HTTP/1.1 200 OK_15Date: Tue, 24 Jan 2023 07:49:10 GMT_15Content-Length: 4_15Content-Type: text/plain; charset=utf-8_15_15test%
Then, how to fix those problem? Fun fact, even using text/template
it won't help to preventing XSS, since it does not sanitize user input. The correct solution is using html/template
_17package main_17_17import (_17 "html/template"_17 "net/http"_17)_17_17func handler(w http.ResponseWriter, r *http.Request) {_17 param1 := r.URL.Query().Get("param1")_17 tmpl := template.New("hello")_17 tmpl, _ = tmpl.Parse(`{{define "T"}}{{.}}{{end}}`)_17 tmpl.ExecuteTemplate(w, "T", param1)_17}_17func main() {_17 http.HandleFunc("/", handler)_17 http.ListenAndServe(":8000", nil)_17}
Let's try again using script alert and other html sample.
_13❯ curl -i http://localhost:8000/\?param1\="<script>alert(1)</script>"_13HTTP/1.1 200 OK_13Date: Tue, 24 Jan 2023 07:55:21 GMT_13Content-Length: 37_13Content-Type: text/plain; charset=utf-8_13_13❯ curl -i http://localhost:8000/\?param1\="<h1>whassup</h1>" _13HTTP/1.1 200 OK_13Date: Tue, 24 Jan 2023 08:01:56 GMT_13Content-Length: 28_13Content-Type: text/plain; charset=utf-8_13_13<h1>whassup</h1>%
Yes, the output properly encoded and sanitized. So using html/template
can prevent xss attack, keep in mind when processing input from user please sanitize first and make sure not trigger script execution that lead to XSS attack.