Lab: Basic server-side template injection (code context)


This lab is vulnerable to server-side template injection due to the way it unsafely uses a Tornado template. To solve the lab, review the Tornado documentation to discover how to execute arbitrary code, then delete the morale.txt file from Carlos's home directory.

You can log in to your own account using the following credentials: wiener:peter


Take a closer look at the "preferred name" functionality.


  1. While proxying traffic through Burp, log in and post a comment on one of the blog posts.
  2. Notice that on the "My account" page, you can select whether you want the site to use your full name, first name, or nickname. When you submit your choice, a POST request sets the value of the parameter blog-post-author-display to either, user.first_name, or user.nickname. When you load the page containing your comment, the name above your comment is updated based on the current value of this parameter.
  3. In Burp, go to "Proxy" > "HTTP history" and find the request that sets this parameter, namely POST /my-account/change-blog-post-author-display, and send it to Burp Repeater.
  4. Study the Tornado documentation to discover that template expressions are surrounded with double curly braces, such as {{someExpression}}. In Burp Repeater, notice that you can escape out of the expression and inject arbitrary template syntax as follows:}}{{7*7}}
  5. Reload the page containing your test comment. Notice that the username now says Peter Wiener49}}, indicating that a server-side template injection vulnerability may exist in the code context.
  6. In the Tornado documentation, identify the syntax for executing arbitrary Python:

    {% somePython %}
  7. Study the Python documentation to discover that by importing the os module, you can use the system() method to execute arbitrary system commands.
  8. Combine this knowledge to construct a payload that deletes Carlos's file:

    {% import os %} {{os.system('rm /home/carlos/morale.txt')
  9. In Burp Repeater, go back to POST /my-account/change-blog-post-author-display. Break out of the expression, and inject your payload into the parameter, remembering to URL-encode it as follows:}}{%25+import+os+%25}{{os.system('rm%20/home/carlos/morale.txt')
  10. Reload the page containing your comment to execute the template and solve the lab.

Community solutions