Xssmaze
Request logging, in place of Kemal's Log-based handler. One line per
request, columns that stay put, and the status code carrying the colour:
14:02:11 200 GET /basic/level1/?query=a 1.2ms
Constants
Single source of truth: read the version straight from shard.yml at compile time so it can never drift from the released version again.
Class methods
Strip CR/LF/NUL from a value before it goes into a response header.
This is NOT the lab going soft on itself. Crystal's HTTP::Headers
raises ArgumentError on a control character, so a payload like
?query=a%0d%0aX-Evil:1 never produced a split response — it produced a
500 and a stack trace, killing the maze's real lesson (the value is
still reflected into the header, which is what header-context tests
need). Sanitizing here keeps the reflection and drops the crash.
Escapes & < > " ' — byte-for-byte what the previous hand-rolled chain of
five gsubs produced, in a single pass instead of five intermediates.
name/url/desc/method/params are the original positional
contract and must stay put — every existing call site depends on it.
Everything after params is structured vulnerability metadata, passed
by keyword; see Maze for the schema. Omitting them leaves the endpoint
"unclassified" rather than silently guessing.