-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-30119: Fix ftplib to handle the ftp user's commands. #1214
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
Conversation
@corona10, thanks for your PR! By analyzing the history of the files in this pull request, we identified @tim-one, @freddrake and @giampaolo to be potential reviewers. |
@giampaolo If you have times, Can you take a look? |
f45e6da
to
0c476ff
Compare
I'm not sure I fully understand the nature of this security issue but at a first look it seems it's the server which is more subject to risks, not the client (but I may be wrong). Also, http://blog.blindspotsecurity.com/2017/02/advisory-javapython-ftp-injections.html suggests this is more about urllib/2 rather than ftplib. In your patch you are disallowing any command with "\r" or "\n" in it, such as Also and I don't see why |
@giampaolo The ftp client will automatically append CRLF to the end of the command. One option is to allow CRLF at the end of the command.
|
Yes, I agree it's probably a good idea to disallow a command containing CRLF. I would not introduce a new exception for that though (not worth it). You can add that check in |
@giampaolo
|
Right. Also, I'm not sure this change solves the vulnerability issue about the CRLF injection. I expect urllib/2 needs to be fixed for that (a PR is welcome :P). As such Misc/NEWS should be changed in accordance. |
@giampaolo Yes, I submitted the patch for that issue also. |
82614d0
to
da6888e
Compare
@giampaolo |
By
I think that we can deny all of the commands which include |
@giampaolo Can I proceed this PR? |
Whereas I agree doing this in urllib is a good idea as I see you've done in #1216 I'm not so sure about ftplib. From a security perspective I don't I understand which are the risks of allowing |
@giampaolo I wrote about more discuss on bpo-30119 |
IMO an FTP server (or firewall parsing the FTP connection) is likely to recognize a lone LF (\n) as a command-line delimiter. The first FTP server I tried does so: >>> s = create_connection(("ftp.debian.org", "ftp"))
>>> s.recv(100)
b'220 ftp.debian.org FTP server\r\n'
>>> s.sendall(b"USER %b\r\n" % b"anonymous\nQUIT") # Injection via LF only
>>> s.recv(100) # Responses to both commands
b'331 Please specify the password.\r\n221 Goodbye.\r\n' Assuming CR is supposed to be illegal in an FTP command line, the client shouldn’t be sending CR either. This may be less important because servers are less likely to interpret it as the end of a command, but it still seems plausible. Python’s own universal newline decoders accept CR as a newline. |
Hi Everyone, I'm the guy that worked out how to exploit these bugs with firewalls. I just figured I would chime in and provide some opinions. For one, any URL parsing code that is not FTP-specific should not have input validation checks added. After all, other protocols might be able to handle CR/LF/NUL just fine through an appropriate encoding mechanism. I don't think you guys were pushing for URL library management of this problem, but I just want to emphasize that. I think any FTP command should be checked for both CR and LF. If either exist, an exception should be thrown, as you appear to be doing. This check should be performed just before sending it on the TCP connection. It is much safer to do this rather than trying to do something hacky like replace them with a space character. (Cleaning invalid input and continuing to use it is often a recipe for disaster in security.) I don't see a good reason to allow CR/LF at the end of the command... I mean, why? Just make the caller strip any string. If FTP happened to have some way to properly encode delimiter characters like this, then that would be the right way to fix it, but there isn't a standard way, so throwing exceptions is your best bet. NUL (\0) bytes should also be viewed with skepticism. For instance, if the FTP command is a If the FTP implementation is designed as a low-level library for use by python programmers without support for URL fetching, should you bother with this stuff? Yes, I think so. The risk might currently be very low, but later someone could wrap up your library with something that accepts URLs and runs some commands. Their library may not be able to deal with these special characters, since it may be too abstract at that layer. So if a command isn't syntactically legal, then blow up at the low level. HTH, |
Again, this was created as a security concern but I fail to see an exhaustive description of how exactly this should have security implications or some sort of CVE about it. I re-read your blog post once again but I fail to understand the implications. The only thing I grasped is that some FTP servers erroneously treat Security concerns aside, there is the argument of rejecting
RFC-2640 describes how to escape them though:
Now, ftplib does not do this (escaping), meaning it's not fully RFC-2640 compliant although it does encode strings. The thing I'm worried about is breaking apps of those users who for some reason use @ecbftw you state you don't want to disclose the exploit script so maybe you can send it to me privately? |
Thank you @giampaolo. And thank you @corona10 for the initial patch. |
This needs backports for Python 2.7, 3.3, 3.4, 3.5 and 3.6. @corona10 would you be up to it? |
GH-2886 is a backport of this pull request to the 3.6 branch. |
GH-2887 is a backport of this pull request to the 3.5 branch. |
GH-2894 is a backport of this pull request to the 2.7 branch. |
bpo-30119: Handle ftp user command.
See https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2017-3533
and http://blog.blindspotsecurity.com/2017/02/advisory-javapython-ftp-injections.html
https://bugs.python.org/issue30119