BlockPixel Goods
A three-person indie shop that prints custom pixel-art apparel. Customers can put their own gamer-tag and a one-line slogan on every product. The personalize-this-item preview goes through the storefront's templating layer.
The Scenario
BlockPixel Goods is Maya, Theo, and Reese — three friends who met at
a craft fair in Portland in 2022 and started selling pixel-art hoodies
from a garage. They graduated to a real shop in 2024 and added the
"Make It Yours" personalization flow last spring, when a customer
asked if she could put her Minecraft realm's name on a tote bag for
her sister. Maya wired the preview page up in an afternoon.
Challenge Intel
Synopsis
The "personalize this item" preview folds the customer's slogan directly into a Jinja2 template string and renders it server-side. No sandbox, no filter — the slogan field is template syntax.
What It Is
BlockPixel's /customize/<product> page accepts a customer's gamer-tag and a short slogan, then renders a preview card showing how the print will look. The preview endpoint builds the template string by string-concatenating the slogan into a Jinja2 template and passing it to flask.render_template_string. That's classic SSTI: `{{7*7}}` in the slogan field becomes `49` in the rendered card, and the standard `__class__.__mro__[1].__subclasses__()` walk reaches `os.popen` to read /flag.txt. The vulnerability is in one place, there are no filters, and the output is reflected directly. Easy-tier scope, deliberately — this is where players learn the Jinja2 SSTI primitive before they meet the sandboxed and blind variants.
Who It's For
Players who have heard of "server-side template injection" and want to see the canonical Jinja2 case in a real product feature. Prereq: comfort with web forms and basic Python attribute traversal.
Skills You'll Practice
- Recognising Jinja2 template echo (`{{7*7}}` → `49`) as a primitive
- Walking `__class__.__mro__[1].__subclasses__()` to reach a useful gadget
- Invoking `os.popen` from a subclass `__init__.__globals__` chain
- Reading flag content out of the rendered preview
What You'll Gain
- Mental model for why concatenating user input into a template string is the wrong shape
- Memorised payload skeleton for unsandboxed Jinja2 SSTI
Ready to hack BlockPixel Goods?
Upgrade to Pro to unlock this challenge and the full library.