$ cat writeup.md…
$ cat writeup.md…
broncoctf2026
Task: Flask+SQLite book search where a forbidden book is hidden via an is_secret=0 filter in the SQL WHERE clause. Solution: SQLi in the ?search= LIKE clause — close the parenthesis and comment out the is_secret filter with `-- ` to reveal the secret book and its flag.
I have recently gained access to these Forbidden Archives, though I've been trying to access a book titled 'All of the World's Knowledge' and it seems like there's another level of security as the high council of wizards have made it forbidden. Is there a way I can get around that?
English summary: A Flask/Werkzeug book-search web app exposes a single GET parameter /?search=. One book, "All of the World's Knowledge", is marked forbidden and filtered out. The goal is to bypass that access control and read the book (which contains the flag).
The site is a Flask/Werkzeug 3.1.8 app (Python 3.14.6) with a single GET search field /?search=. It queries a SQLite backend, and the query suffix is:
... LIKE '%<search>%') AND is_secret = 0 LIMIT 1
The forbidden book "All of the World's Knowledge" has is_secret = 1, so the AND is_secret = 0 clause filters it out of normal results. Authorization is enforced only in the SQL WHERE clause — there is no separate access-control check — which makes it bypassable through SQL injection.
The search parameter is directly interpolated into the LIKE expression, so it is injectable. Notes:
robots.txt, .git/HEAD, .env all returned 404 — no exposed source or config.OR- and UNION-based SQLi payloads were stripped/filtered by keyword filtering, so classic boolean/union injection did not work.The keyword filter blocks OR/UNION but does not block SQL comments, so a comment-based filter bypass works.
The payload closes the LIKE string and its parenthesis, then uses a SQL comment (-- ) to neutralize the trailing AND is_secret = 0 filter, returning all rows including the secret one.
Injected payload: Knowledge%') -- (note the trailing space after --, required for SQLite line comments).
Resulting query fragment:
LIKE '%Knowledge%') -- %') AND is_secret = 0 LIMIT 1
Everything after -- is a comment, so the is_secret filter is gone.
curl -sS --get \ --data-urlencode "search=Knowledge%') -- " \ 'https://broncoctf-forbidden-archives.chals.io/'
The response returns the book "All of the World's Knowledge" with the flag inside a <p> in the book card.
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar