-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Double Content-Type headers added to request if context->http->header is a multiline string #18238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @pharrison-weiss. HTTP uses CRLF line endings. If you replace |
Thanks, not sure where I read to use PHP_EOL but we're switching to arrays at this point in any case. I'd still consider it an issue because (1) the other headers are being picked up by most web servers so it's not going to be immediately obvious there's an issue (indeed, we were alerted to the issue because a certain major CRM provider's API was updated to validate the Content-Type field, and it's complaining about there being two Content-Types) and (2) it's silent and extremely difficult to see why it's failing (unless there's some way to dump sent headers that I'm unaware of?) But I guess it's changing from a "Good configuration is failing" to "Bad configuration isn't being rejected/properly warned about" type thing. Which under certain circumstances wouldn't be a major issue, it's just, like I said, almost impossible to debug short of doing what we did above with Netcat, and warnings will only be issued under some circumstances and then only a misleading one. |
Tools are often forgiving, but the standard is clear. I'll pass this along to @bukka to decide whether we want to do the same. |
I did a bit of checking and thinking about this. Currently, we don't do any validation of request header values. In this case, it's not actually strictly wrong, because RFC 9110 places the requirement on the recipient, not the sender. Specifically, this is defined in section 5.5:
Unless I missed something in the RFC, this is not strictly prohibited on the sender side. So I don't think we can treat this as a bug. The thing is, there might be some testing applications that are used to test receivers by intentionally sending invalid headers. If we change this, we could potentially break those — which is something we want to avoid in a bug-fix release if we don’t have to. That said, I do think we should introduce some validation by default as a feature (targeting the master branch). Not doing any validation is dangerous, can lead to unexpected results, and may even have security implications. (While the security issue would technically be on the recipient side in this case, it's better to prevent it on the sender side anyway.) To allow such testing tools to continue working, we should add a boolean context option that allows disabling this validation. |
Description
When using file_get_contents to post an HTTP/HTTPS request, context->http->header can either be a string or an array of strings. If a string, it may ignore the header containing a Content-Type line and add an additional one.
The following code:
Resulted in this request (captured using netcat):
But I expected this output instead:
Commentary:
There is a warning, "file_get_contents(): Content-type not specified assuming application/x-www-form-urlencoded", that is on some occasions issued (although not, oddly enough, for the code we tracked down this issue as applying to.)
The issue goes away if you build context->http->header as an array.
While arguably building the header as a multiline string seems (always seemed) odd to me, it's frequently quoted in examples across the Internet (which is probably how we ended up doing it) - several examples here: https://www.php.net/manual/en/function.stream-context-create.php
I doubt there are any backward compatibility issues that would be caused by a straight fix to this.
PHP Version
PHP 8.1.2
Operating System
Ubuntu 22.04
The text was updated successfully, but these errors were encountered: