Need a quick three-line HTML wrapper to test something browser-related? Like, does this page still work if wrapped in an iframe? Does <video src=javascript:blah> run the javascript? This might help.
url: 'https://4i.am/:' pairs
pairs: pair ('&' pair)*
pair: lhs '=' text
| lhs ':=' modifier '[' nested-text ']'
| lhs
lhs: word -- attribute
| word '[' things ']' -- tag
Any request to 4i.am where the path starts with /: (or the query starts with ?:) returns a dummy page based on the contents of the URL:
/:raw=<h2>helloRaw output (no content type)
/:Content-Type=text/plain&raw=<h2>helloSet HTTP headers (note that you don't repeat the : for each argument)
/ignored.html?:CT=text/plain&raw=<h2>helloYou can put the instructions in the path or in the query string; whichever one starts with a : is used. (MSIE will content-type sniff this one)
/:401&CT=text/plain&WAuth=basic+realm=HelloHTTP status codes. Headers can be abbreviated as long as they are unique.
/:a[href=/&target=_blank]=Click+meGenerate HTML tags (this also sets the content-type)
/:img[src:=[/:401&WAuth=basic+realm=Hello]]name:=[...] syntax lets you have embedded & characters; useful if you want to link back to this.
/:img[src:=[//not.alf.nu/:401&WAuth=basic+realm=Hello]]A different origin (Chrome will not prompt for this one)
/:img[src:=u[/:301&Location:=u[//not.alf.nu/:401&WAuth=basic+realm=Hello]]]Arguments are URL-decoded by default. You can use :=u[...] to avoid that so you can nest things properly without a %252525 nightmare. (Chrome prompts for this one)
/:body[background:=[/:CT=text/plain&raw:=64[iVBORw0KGgoAAAANSUhEUgAAAAIAAAABAQAAAADcWUInAAAACklEQVQI12NwAAAAQgBBg7nsrQAAAABJRU5ErkJggg]]]If the quoting gets in the way you can fall back to base64 for any argument.
/:iframe[srcdoc:=r[text=123&marquee[]=foo]]Run a nested version of this and generate HTML.
/:iframe[src:=d[script[]=alert(document.domain)]]Same, but generate a data URL (this is same-origin in Firefox)
/:body[background=/:png=ffcccc]&img[100x100&src:=d[png=003-t-t-t-003/t//0-t---0/t-0---t]]You can generate tiny PNGs by listing a bunch of RGB values, one per pixel.
For services that parse/unparse other people URLs, you can also use (,) instead of [&].
This also works on attacker.website if you want to make a more readable example.
Complaints to @steike