> Are you suggesting that if the backend server was setup as an HTTP proxy, you could get the backend server to proxy the merged request somewhere else?
I'm suggesting that since the back-end server may see the requests as a single request with the second request as part of teh payload of your crafted request, the question then becomes one of "In what ways can I get this site to show one of my params". That's similar to a CSRF, but simpler in that that you don't care that it's unescaped, you just care that it's in the source in some way, since it's what should be displayed back to you for your request.
My form example is straightforward. Imagine you are requesting http://slack.com/help/search. If you reorder the params slightly, such that the "query" param is last, you might get a good chunk of the next request to be sent to the back-end as your query param, which slack will helpfully display for you both on the page and in in the search input on the resulting page. It will clean our newlines, and likely some other characters, but that hardly seems a problem.
> I.e. you're suggesting basically using this as a CSRF attack to post part of the victims request (including secret cookie) somewhere public to retrieve later?
Yep.
> I think this would work in certain situations but would be difficult to pull off. Its a bit more complicated because if the site was using csrf tokens...
I just found one and used it in an example above. Took me less than 5 minutes (I tried a different form that did have a csrf token first).
> The bigger issue is the request body would be kind of malformed.
That's a problem for if you want it to look legit to someone else. If you just have to note that it has the equivalent of /\sCookie:\s(\S+)\s/ in it... well that's not too bad. Removing the newlines makes it all one string, but in the example above they helpfully replace them with spaces. Even if they didn't, it's probably not hard to see where the next header begins.
> I guess the biggest issue is if ; is considered a form field separator (since user-agent usually has ; in it).
Depends on how you do it. My example above uses GET, so any ampersand (which is probably likely to exist in many queries) will throw it off. A POST might offer more options. Even with the GET, you might be able to run it enough times to find a post as the included second request, and that's less likely to have an ampersand in the URL, and you would probably scoop up all the headers at least. If you post with multipart mime, depending on how lenient it is on a final terminator, you might not have any problem at all if you find the right page to post to.
I did just confirm that that same search page doesn't seem to honor params passed in a POST, so that's good (for Slack).
I think the bottom line is that once you can make part or all of someone else's HTTP request show as part of your request's payload, it's a drastically lower bar for exploiting, as there are many possible ways to exfiltrate the data at that point, and they only have to screw up by allowing one of them to work.