EllisLab/CodeIgniter — pull request #762 by dchill42 (2011-12-09 20:36:11+00:00)
Title: Hotfix for broken _remove_evil_attributes() in XSS Security

A recent change to the _remove_evil_attributes() function - part of the xss_clean() suite in Security.php - left it broken, or at least differently broken than it may have been before. I ran across the following string to be cleaned:

```This is a test```

Which got converted into:

``````

The first regex pattern inside the loop eats everything that's not a space after an evil attribute. At very least, it needs to stop at a > character. While debugging and testing, I also noticed that the second regex pattern used duplicates the work of the first, in that the first is already picking up quoted attributes.

Thus, I worked out a replacement regex that analyzes each tag, stripping out evil attributes as it goes. This one will recognize attributes with single, double, or no quotes and accurately detect the end of each value. The pattern represents one full open or close tag - start to end - and will not get tripped up on '>' characters within valid quoted attributes. That is, if you tested this silly but technically valid string:

```This is a test```

...it would parse the entire span open tag, recognizing it with four attributes, and successfully remove the two evil ones. The regex also happens to be pretty about eating the preceding whitespace with each evil attribute it removes.

Finally, for a little bit of extra efficiency, the expression is assembled once outside the while loop to avoid implode() and string concatenation on each iteration, as this loop will run at least twice for any string containing an evil attribute.