MetaCTF ⚑
Challenge categories: Web Exploitation
Challenge Name: Library
Challenge Link: https://compete.metactf.com/291/problems
Tools: Manually.
Challenge Description:
In this challenge, we are performing a penetration test on a small book library app built in the Go language that appears to exhibit some abnormal behaviour. The app is designed to process book requests, but certain endpoints return unexpected responses. The objective is to identify the root cause—whether it’s a coding bug, improper input validation, or potentially a security vulnerability in the request handling. This exercise will challenge your ability to analyze code logic and identify security flaws that could compromise the app's functionality or expose it to attacks.
The challenge description contained the source code download link with a live web application to perform the penetration testing.

Application Dashboard:
Open the provided link in the browser to access the library dashboard, where we can find a welcome message and a list of available books. You can also view the details of each book.

Source Code Review:
Download the application's source code using the given link in the challenge description.
The application source code file contained two “.html“ files and one “main.go” file, which contained all the backed code of the application.
The home.html file contains an HTML template snippet that is likely used in a Go (Golang) web application. It dynamically generates a list of books, with each book title rendered as a hyperlink. The syntax {{range .}} indicates the use of Go's templating engine, which is commonly used for web applications built using Go.
<home.html>

<ul>
element creates an unordered list that will be dynamically populated with <li>
(list items). The {{range.}}
syntax is part of Go’s templating system and is used for iterating over a collection. The dot (.
) represents the current context passed into the template, which in this case likely refers to a list of book objects. This indicates that the template expects to receive a slice or array of books, with each book being iterated over within the {{range.}}
block.In the range loop, a list item (<li>
) is created for each book in the collection.
The <a href="/books?book={{.Param}}">{{.Title}}</a>
tag adds a clickable link for each book. The link is used {{.Param}}
as a query parameter, which is likely a unique ID or identifier for the book. Inside the link, {{.Title}}
displays the book's title as clickable text.
The {{end}}
marks the end of the {{range .}}
loop, indicating where the iteration stops.
<book.html>
<p>
tag.
In the above image, the <p>
tag is used to display a paragraph of text. {{.}}
is Go's template syntax, where the dot (.
) refers to the current data passed to the template. In this case, it represents a string of book content. When the page loads, {{.}}
will be replaced with the actual content of the book.
The Go file (main.go)
is a simple web server application that provides book-related content via Go's HTTP package and templating engine. It defines a ReadBook
structure with a method that reads a file's content and returns it as a string while handling any file reading errors.
The application stores a hardcoded map of books (books)
, with each key-value pair representing a book identifier and description. The application also includes two HTTP handlers: homeHandler
, which generates a homepage listing available books using the home.html
template, and bookHandler
, which retrieves and displays individual book content based on the query parameter book using the book.html
template.
<main.go>

Vulnerable Code: The provided Go code is vulnerable to Server-Side Template Injection (SSTI) in the bookHandler function. below the vulnerable part of the code.

book
query parameter from the URL (userBook
) and directly passes it to the template.New("book").Parse()
function, without any sanitization or validation.This can result in template injection if an attacker supplies malicious input through the book
parameter. Since Go templates allow for the execution of code within {{ ... }}
attacker could potentially inject arbitrary template code that gets executed on the server.
To get the flag from the server, we have to use the constructed below payload.
Payload: /books?book={{.ReadBook%20"flag.txt"}}
In this payload the {{.ReadBook "flag.txt"}}
is a Go template syntax where .ReadBook
refers to the ReadBook
method defined in the application. The injected payload attempts to call the ReadBook
method to read a file called "flag.tx
".
Exploitation Part:
Step 1. Open the link given in the challenge description.



Mitigation Part
To mitigate the SSTI risk:
Remove Dynamic Parsing: Never send user input directly to the template parser.
Validate Input: Use only predefined values (such as book IDs) in the template and reject any untrusted or unexpected entries.
Fixed Code for bookHandler
function
func bookHandler(w http.ResponseWriter, r *http.Request) {
userBook := r.URL.Query().Get("book")
bookContent, validBook := books[userBook]
if validBook {
tmpl := template.Must(template.ParseFiles("templates/book.html"))
tmpl.Execute(w, bookContent)
return
}
http.Error(w, "No valid book specified", http.StatusBadRequest)
}
- Removed Dynamic Template Parsing: The
template.New("book").Parse(userBook)
section has been removed to avoid processing untrusted input. - Only Predefined Books: The code now only renders templates for books that exist in the
books
map, preventing arbitrary template execution.
Reference: Server-side template injection: https://portswigger.net/web-security/server-side-template-injection
HackTricks: https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#ssti-in-go
Payatu : https://payatu.com/blog/ssti-in-golang/
w3school : https://www.w3schools.com/go/
_____________________________________________________________________
Connect:
LinkedIn: https://www.linkedin.com/in/sudeeplamsoge/
Twitter : https://x.com/SudeepLamsoge
Comments & Suggestions are always welcome. :)