alf.nu / @steike

Chargen

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>hello

Raw output (no content type)

/:Content-Type=text/plain&raw=<h2>hello

Set HTTP headers (note that you don't repeat the : for each argument)

/ignored.html?:CT=text/plain&raw=<h2>hello

You 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=Hello

HTTP status codes. Headers can be abbreviated as long as they are unique.

/:a[href=/&target=_blank]=Click+me

Generate 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 or @steike.