module Xssmaze

Overview

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

Defined in:

assets.cr
registry.cr
request_log.cr

Constant Summary

VERSION = {{ ((read_file("/srv/crystaldoc.info/github-hahwul-xssmaze-v0.3.0/src/../shard.yml")).lines.find(&.starts_with?("version:")).split(":"))[1].strip }}

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 Method Summary

Class Method Detail

def self.freeze! #

[View source]
def self.get : Array(Maze) #

[View source]
def self.grouped_mazes : Hash(String, Array(Maze)) #

[View source]
def self.gzip(body : String) : Bytes #

[View source]
def self.header_value(s : String) : String #

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.


[View source]
def self.html_escape(s : String) : String #

Escapes & < > " ' — byte-for-byte what the previous hand-rolled chain of five gsubs produced, in a single pass instead of five intermediates.


[View source]
def self.push(name : String, url : String, desc : String, method : String = "GET", params : Array(String) = ["query"], vuln : String = "unclassified", sources : Array(String) = [] of String, sinks : Array(String) = [] of String, delivery : Array(String) = [] of String, exploitable : Bool = true, note : String | Nil = nil) #

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.


[View source]