Widgets

context: client-side DOM sinks

1. Signature widget

Your signature: guest

This widget reads location.hash and drops it into innerHTML. Nothing is sent to the server - the sink is entirely client-side, so your payload goes in the #fragment and never leaves the browser. Prove it by calling /m03/api/solve/dom_hash from your payload.

2. Welcome banner

This banner personalises from the ?name= query parameter.

The name parameter is read client-side and passed to document.write(). Different sink, different escaping rules. Prove execution via /m03/api/solve/dom_write.

3. Rich-text preview

Pass ?html= to preview sanitised rich text here.

This one does sanitise: it strips script tags and on*= handlers from your string, assigns it, then re-reads and re-assigns its own innerHTML. The browser's re-parse step is where naive string sanitisers fall apart - find markup that mutates into something dangerous only after that round-trip. Prove it via /m03/api/solve/mxss.