SSTI CTF Challenge 1

Abishek KafleAbishek Kafle
2 min read

Lab Setup

  1. Create a folder for the challenge.

     mkdir ssti_ctf1_challenge
     cd ssti_ctf1_challenge
    
  2. Set up the environment

     python3 -m venv venv
     source venv/bin/activate 
     pip install Flask
    
  3. Create app.py

     from flask import Flask, request, render_template_string
    
     app = Flask(__name__)
    
     @app.route('/')
     def index():
         return '''
             <h1>Welcome to the SSTI CTF Challenge!</h1>
             <form method="POST" action="/submit">
                 <input type="text" name="user_input" placeholder="Enter your name" />
                 <input type="submit" value="Submit" />
             </form>
         '''
    
     @app.route('/submit', methods=['POST'])
     def submit():
         user_input = request.form['user_input']
         # Intentionally vulnerable: rendering user input directly in the template
         template = f'''
             <h1>Hello, {user_input}!</h1>
             <p>Your input has been rendered. Try to exploit it!</p>
         '''
         return render_template_string(template)
    
     if __name__ == '__main__':
         app.run(debug=True)
    
  4. Run the Application

     python app.py
    
  5. We now have our web app ready.

  6. Try the SSTI payload now and submit:

    - {{ 7*7 }}

  7. Now we can see that we get 49, which means our SSTI payload is working.

    Causes of this vulnerability

    1. Direct Rendering: User input is directly rendered in the template with f-strings, allowing attackers to use template syntax.

    2. Lack of Validation/Sanitization: No validation or escaping of user_input lets attackers inject harmful payloads.

Code Review

  1. Vulnerable code

       user_input = request.form['user_input']
         # Vulnerable to SSTI: directly rendering user input
         template = f'''
             <h1>Hello, {user_input}!</h1>
             <p>Your input has been rendered. Try to exploit it!</p>
    
  2. Prevention Code

  • Use the built-in escape function for user input.

  • Avoid rendering user input directly.

 user_input = request.form['user_input']
safe_input = escape(user_input) 
template = f'''
    <h1>Hello, {safe_input}!</h1>
'''

#hacking #securecodereview #ssti #happyhacking

0
Subscribe to my newsletter

Read articles from Abishek Kafle directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abishek Kafle
Abishek Kafle

Infosec Poet and CAP-certified DevOps/SecOps Engineer, passionate about security, creativity, and continuous learning.