-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
Feature request: Do not allow "downgrading" protocol on redirect #226
Comments
The URL is at some point known in advance though. Your application passes the URL to libcurl so it would know the URL. My opinion is that seems like a niche to implement in your application. Though I agree maybe some special generic type defines could be helpful. I'm not interested in taking this issue up really but I just wrote Something like CURLPROTO_ENCRYPTED_ONLY ? maybe would be easier and simpler as a combination of the flags of encrypted protocols. What seems difficult is handling connections that are "upgraded" to encryption. You'd have to allow the unencrypted protocol and then make sure they upgrade. |
Hello Jay, many thanks for jumping in. I think your I like your second proposal About it being niche request, I don't agree; if securing a transaction is important, protocol downgrade is a real concern and dealing with this currently needs extra logic on the caller side (parsing the protocol in the source URL and forming a protocol filter based on that). Such extra logic may not always be trivial to implement, especially in scripts. For these reasons, I hope to see your patch promoted to a PR and seeing it in a future curl version. In the meantime any opinion and discussion is welcome. |
|
The scope seems pretty narrow to me. What can cause a follow besides an http or https response? Nothing, it appears, which I didn't realize until I was most of the way through implementing Something that stops the downgrade might be better and by making it just another flag that can be used in combination we're back to Viktor's suggestion. If the user doesn't want ambiguity they'd have to know the protocols they're expecting though. Consider: curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS,
CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_NO_DOWNGRADE); And behavior like: |
My original proposal was about to allow that, even though it's not something secure to do because the redirection target can be spoofed in the plaintext phase. In such case it's best to switch the origin URL to a secure alternative to keep the complete redirection chain use secure protocols. 'NO_DOWNGRADE' also reintroduces the ambiguity regarding what counts as a "downgrade" (f.e. is it an HTTPS to FTPS redirection considered a downgrade?), this is well mitigated by the optional selection of allowed protocols, it's good idea. Though internally, curl will still have to maintain a protocol list sorted by "upgrade" order. My preference is still towards 'staysame', but if you guys find it better to allow "upgrades" as well, it's also an alternative - it gives more control, but some of them will be unsafe, it's up to the user. Another alternative could be called 'STAYSAFE' (or 'STAYENCRYPTED'), and it'd mean that an unencrypted protocol can be changed to anything, while an encrypted protocol can only continue as encrypted - with an optional selection of allowed encrypted protocols. This seems simple, with less ambiguity and it hints no false sense of security about upgrading unencrypted protocols. |
It is also a bit tricky to easily figure out what an encrypted protocol is and thus what the level of the redirected-to protocol is. Like FTP, POP3 etc have "explicit" TLS which means they will connect as normal FTP:// etc and only upgrade to TLS if asked to do so with libcurl options. |
Indeed, the ambiguity is there as well. |
As this is still "just" a feature request and nobody seems to grab it now, I'll close it. This is now mentioned in the TODO: http://curl.haxx.se/docs/todo.html#Refuse_downgrade_redirects |
Viktor those are drafts that are more concept. To reopen would require a different project collaborator who wants to take this on for assignment and explore the issue. To reiterate I think this is just too niche. Most common scenario I see is user wants to stop https->http but you can use |
uhm... I mean |
Thanks for you reply Jay. I'd like to reiterate that http->https is also unsafe. (not only https->http) Hence the recent notion of introducing HSTS in various browsers and creating the protocol for it: HSTS is a wider topic, but the starting point is that http->https redirection is deemed insecure and something to avoid. It'd be nice to see Please note that [1] Google returns 379000 hits for the latter and 4610 for the former. |
I certainly wouldn't mind supporting HSTS, but that would need to be an option that specifies where to save the "cache" for that information - it would be tricky to add just transparently and by default - those "other HTTP clients" you speak of are all browsers I take it?. HSTS is however a slightly different topic than the much simpler option this issue is about. So, this is not shutting down this feature, just that I prefer not to have open issues lingering around if nobody is working on them, especially not for feature requests. |
Sorry for bringing in HSTS, it was solely to make a point on http->https "upgrade" being harmful. "other HTTP clients" are all browsers at this moment, yes (and a recent proposal to implement it in Fully on the same boat about lingering Issues. What is unclear to me is what else work needs to be done here, and is there anything I could help to make this happen? We'd need a conclusion on 'staysafe' vs. 'no-downgrade', and certainly one about it being too niche or useful for inclusion, but the patches (to me) look complete, except regression tests. |
I got the impression none of the patches were suggested for real so I've not bothered about them, and @jay seems to have basically the same view. Sorry if that was wrong. I'll welcome a full patch/pull-request. |
It's rather me having being slow understanding the difference between a "real" patch and the ones @jay created. In some spare I'll try finding out what's missing for the staysame proposal. |
@vszakats it was no pull request and it was not a posted patch, it was a link to a set of commits. A "real" patch would be a patch sent to the mailing list, a pull-request would appear as one here on github. |
As for HSTS, I created a new issue: #1026 |
Is there any progress for now? I try to detect redirects to http which i want to forbid. It would be nice if this feature would be available and also a special exit code to detect if the error was caused by the redirection downgrade. |
My solution/workaround for now is to use curl option [ When the URL is a variable and/or it happens to use |
Currently these useful
curl
/libcurl
options exist to control which protocol a redirection may be allowed to follow:http://curl.haxx.se/docs/manpage.html#--proto-redir
http://curl.haxx.se/libcurl/c/CURLOPT_REDIR_PROTOCOLS.html
But, in case the URL is not known in advance (f.e. it is coming from user input), there is no simple way to disable unwanted downgrades of the protocol in a generic way, f.e. (and typically) from HTTPS to HTTP.
For HTTPS URLs, the allowed redirects should be HTTPS (only), while for HTTP URLs, both HTTP and HTTPS would be acceptable.
One way to implement this, would be to allow specifying a special protocol
safer
(--proto-redir =safer
andCURLPROTO_SAFER
), which would only allow protocols regarded as equally safe or safer than the one used in the original URL. [I'm not insisting on this particular terminology]Regarding all supported protocols, this may be a possible categorization of all of them based on a generally accepted amount of safety they provide, ordered by decreasing safety category:
"Safest" (SSL/TLS or SSH):
CURLPROTO_HTTPS
CURLPROTO_SCP
CURLPROTO_SFTP
CURLPROTO_SMTPS
CURLPROTO_IMAPS
CURLPROTO_POP3S
CURLPROTO_RTMPS
CURLPROTO_RTMPTS
"Safe" (plaintext implicitly or explicitly upgraded to SSL/TLS):
CURLPROTO_LDAPS
CURLPROTO_FTPS
"Unsafe" (plaintext):
CURLPROTO_HTTP
CURLPROTO_FTP
CURLPROTO_FILE
CURLPROTO_DICT
CURLPROTO_GOPHER
CURLPROTO_IMAP
CURLPROTO_LDAP
CURLPROTO_POP3
CURLPROTO_RTMP
CURLPROTO_RTMPE
CURLPROTO_RTMPT
CURLPROTO_RTMPTE
CURLPROTO_RTSP
CURLPROTO_SMB
CURLPROTO_SMTP
CURLPROTO_TELNET
CURLPROTO_TFTP
The text was updated successfully, but these errors were encountered: