title: Regex and the "war" on XSS
body: <p>I've always been interested in writing web software like forums or blogs, things which take a limited markup to rewrite into HTML.  But lately, I've noticed more and more that for PHP, try googling "PHP BBCode parser -PEAR" and test a few out, you either get an inefficient mess, or you get poor code with XSS holes here and there.</p>
  
  <p>Taking my previously mentioned example, of the poor BBCode parsers out there, how would you avoid XSS?  I'll now take your typical regular expression for handling a link, and you can mention how vulnerable it is and how to avoid it.</p>
  
  <pre><code>// Assume input has already been encoded by htmlspecialchars with ENT_QUOTES
  $text = preg_replace('#\[url\](.*?)\[/url\]#i','&lt;a href="\1"&gt;\1&lt;/a&gt;', $text);
  $text = preg_replace('#\[url=(.*?)\](.*?)\[/url\]#i','&lt;a href="\1"&gt;\2&lt;/a&gt;', $text);
  </code></pre>
  
  <p>Handling image tags are hardly more secure than this.</p>
  
  <p>So I have several specific questions, mostly specific to PHP implementations.</p>
  
  <ol>
  <li>Is it better practice, in this example, to only match using a uri/url validation expression?  Or, is it better to use <code>(.*?)</code> and a callback, then ascertain whether or not the input is a valid link?  As would be obvious above, the <code>javascript:alert('XSS!')</code> would work in the above URL tags, but would fail if the uri-matching was done.</li>
  <li>What about functions like <code>urlencode()</code> within a callback, would they be any deterrence or problem (as far as URI standards go)?</li>
  <li>Would it be safer to write a full-stack parser?  Or, is the time and processing power needed to develop and use such a thing too weighty for something handling several different entries per page?</li>
  </ol>
  
  <p>I know my example is one of many, and is more specific than some.  However, don't shirk from providing your own.  <em>So, I'm looking for principles and best practices, and general recommendations for XSS-protection in a text-parsing situation.</em></p>