There are numerous references to HTTP Response Splitting (HRS) vulnerabilities with PHP having been resolved since 4.4.2 and 5.1.2 (E.g. https://en.wikipedia.org/wiki/HTTP_response_splitting), or for around 9 years.

And yet CVE-2013-2652 reported a vulnerability in WebCollab using PHP, even though the proof-of-concept (http://archives.neohapsis.com/archives/bugtraq/2013-10/0117.html) specified a PHP version of 5.4.7. The problem identification uses "%0d%0a" in its problem statement.

I have experimented with PHP myself and it does indeed avoid allowing insertion of the 2-byte hex sequence 0x0d0x0a, but it does not prevent insertion of the %-encoded equivalent 6-character sequence %0d%0a.

On the surface at least, this seems to be a bit of a contradiction. I.e. that either 1) PHP is not as HRS-safe as suggested since it allows the 6-character sequence "%0d%0a" to be inserted into a header or 2) the stated vulnerability in CVE-2013-2652 (that "%0d%0a" was allowed to be written by a PHP application) was at least significantly overstated.

Which of those is true? (Or is it something else entirely?)

(Notes: a) I fully understand that it's better to validate or sanitize user-supplied data regardless of what other protections are in place. b) The WebCollab fix was quite straightforward and does just that: validate the user-supplied input for allowed characters. I'm more interested here in the robustness of PHP's HRS-safety, and the nature of any danger, if it exists.)

  • Note that the POC uses %0d%0a%20, not %0d%0a. The first is allowed, the second is not (at least in newer PHP versions it will throw a warning: Warning: Header may not contain more than a single header, new line detected). This seems to be a problem for IE (see eg here)
    – tim
    Dec 22, 2015 at 13:32

1 Answer 1


@tim is right. The exploit uses the sequence %0D%0A%20 which is URL-decoded to CR + LF + SPACE and thanks to the extra space could bypass the response splitting protection in some browsers.

There was once a feature called line folding that allowed HTTP headers to span over multiple lines by prepending every additional line with a space or tab. It was later dropped in RFC 7230, though. So it happened that Internet Explorer treated header continuations with leading spaces as if they were multiple individual headers while PHP did not yet implement the RFC, leaving IE vulnerable to the space trick. This issue was addressed in February 2015 (bug #68978) and finally implemented in PHP 5.4.38, so version 5.4.7 was still affected back then.

From the changelog for 5.4.38:

Removed support for multi-line headers, as they are deprecated by RFC 7230.

You can see in the corresponding commit that header() now completely rejects any carriage returns and line feeds, regardless of their position. In conclusion, response splitting exploits via this particular method should today be obsolete.

  • Thanks to both of you. That was useful clarifying information.
    – Henry
    Jan 18, 2016 at 14:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .