The CodeIgniter framework contains a function, xss_clean(), which is intended to filter out potential XSS attacks. From the CodeIgniter documentation:

The XSS filter looks for commonly used techniques to trigger Javascript or other types of code that attempt to hijack cookies or do other malicious things. If anything disallowed is encountered it is rendered safe by converting the data to character entities.

I identified a form of malicious input that would bypass the xss_clean() filtering, allowing for arbitrary JavaScript to be executed. The vulnerability has been patched in CodeIgniter 2.1.4. Any developers relying on xss_clean() as a form of protection should upgrade their application to the latest version of the framework.

This vulnerability has been designated CVE-2013-4891.

Vulnerability Details

The vulnerability is straightforward to understand. The xss_clean() function would only strip attributes from HTML tags that were properly closed. However, browsers which see unclosed tags can choose to parse them as though they were properly formed.

In this case, my proof of concept was:

<img src="a" onerror='eval(atob("cHJvbXB0KDEpOw=="))'

The lack of a > at the end meant that the onerror attribute wasn’t stripped by xss_clean(). However, browsers would parse this input as a valid img tag with src and onerror attributes. By using eval and atob, I was able to get arbitrary JavaScript to execute without having to worry about any additional filtering.

Disclosure Timeline

  • March 7th, 2013, 10:24 AM: Initial report to developers via email. Sent proof of concept.
  • March 7th, 2013, 10:27 AM: Reply from developer, investigating report
  • March 18th, 2013, 11:43 AM: Reply from developer, unable to reproduce vulnerability on latest development branch (3.0.x).
  • March 18th, 2013, 12:16 PM: Sent followup to developer, promising to reconfirm proof of concept.
  • March 18th, 2013, 12:50 PM: Email sent to developer confirming that the vulnerability exists in the latest stable release (2.1.3) but not in the development branch.
  • March 18th, 2013, 1:58 PM: Developer replies, looking in to merging fix from development branch into stable.
  • April 13th, 2013: Email to developer asking for status update
  • April 17th, 2013, 11:51 PM: Reply from developer, continuing to work on fix.
  • April 17th, 2013, 11:52 PM: Acknowledged reply from developer.
  • June 26th, 2013: Email to developer, informing them of plans to publish vulnerability details via blog on July 9th.
  • July 5th, 2013, 3:59 PM: Reply from developer. Patch has been applied to stable branch. Requesting confirmation of fix.
  • July 5th, 2013, 5:31 PM: Sent email confirming fix. Request ETA on release of new stable version.
  • July 8th, 2013, 10:13 AM: Reply from developer, planning to release new version within 24 hours.
  • July 8th, 2013, 5:38 PM: Email from developer. CodeIgniter 2.1.4 released publicly.
  • July 8th, 2013, 6:06 PM: Sent email acknowledging public release. Updated plans to publish blog post so that developers would have time to update.
  • July 23rd, 2013: Blog post published.


The xss_clean() function employs multiple blacklists and as such is not a safe solution for preventing XSS. Researchers have discovered bypasses for the filtering in the past [1], [2], [3] and there is no guarantee that more bypasses won’t be discovered in the future.