Start learning free

LESSON 100 OF 173 · BACKEND: USERS AND SECURITY

Escape What You Echo in Go

Practice

The shop's helper writeHTML sends a text as a web page: HTML, with Content-Type: text/html. If that page repeats something a user typed, and they typed <script>alert(1)</script>, the browser runs that script on your site, as whoever is looking at the page. This attack is called XSS (cross-site scripting).

The fix is to escape what you echo. html.EscapeString, from Go's html package, turns < into &lt; and > into &gt;. The browser shows those codes as the characters, and never runs them. For example, on a greeting route:

app.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
	name := cmp.Or(r.URL.Query().Get("name"), "friend")
	writeHTML(w, "Hello, "+html.EscapeString(name)+"!")
})

Here html.EscapeString("<b>Mia</b>") gives &lt;b&gt;Mia&lt;/b&gt;: the visitor sees the tags as text, not a bold name. JSON answers don't need this, because a browser never runs a JSON answer as a page.

Your code must answer these requests. A user signed up with the email <script>alert(1)</script>@evil.com, and an admin added a product named <i>Desk</i>:

GET /welcome  (Authorization: Bearer <token>)
  →  200  Welcome back, &lt;script&gt;alert(1)&lt;/script&gt;@evil.com!
GET /search?q=ot
  →  200  Products matching ot: Notebook, Teapot
GET /search?q=sofa
  →  200  No products match sofa
GET /search?q=<script>alert(1)</script>
  →  200  No products match &lt;script&gt;alert(1)&lt;/script&gt;
GET /search?q=desk
  →  200  Products matching desk: &lt;i&gt;Desk&lt;/i&gt;

Your task: in welcome, answer with writeHTML and the email escaped. Then build GET /search: read q from the query string, collect the names of the products whose name contains it, and answer the no-match text or the names found, with q and the names escaped.


Assignment
Follow the Coding Tutorial to escape the email in /welcome and to build a safe /search page.


Hint
Read the words with r.URL.Query().Get("q") and give the query "%"+q+"%" as its ? value. You can join html.EscapeString(...) to normal text with +: put every part that doesn't come from your own code inside it.


STEP 1 OF 12
    Ctrl + Enter to check

    Sec Xss in Go

    Keep going with Go1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free