You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rewrite CGIHTTPRequestHandler to always use subprocess #61149
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2013-01-12.14:14:43.430>labels= ['type-bug']
title='rewrite CGIHTTPRequestHandler to always use subprocess'updated_at=<Date2013-08-02.06:56:00.467>user='https://bugs.python.org/neologix'
On Unix, CGIHTTPRequestHandler.run_cgi() uses the following code to run a CGI script:
"""
pid = os.fork()
[...]
# Child
try:
try:
os.setuid(nobody)
except OSError:
pass
os.dup2(self.rfile.fileno(), 0)
os.dup2(self.wfile.fileno(), 1)
os.execve(scriptfile, args, env)
"""
It's basically reimplementing subprocess.Popen, with a potential securiy issue: open file descriptors are not closed before exec, which means that the CGI script - which is run as 'nobody' on Unix to reduce its priviledges - can inherit open sockets or files (unless they're close-on-exec)...
The attached patch rewrites run_cgi() to use subprocess on all platorms.
I'm not at all familiar with CGI, so I don't guarantee it's correct, but the regression test test_httpservers passes on Linux.
It leads to cleaner and safer code, so if someone with some httpsever/CGI background could review it, it would be great.
The latest version of the patch passes on Linux, OpenIndiana and Windows.
Note that I did apply the select()-hack on all platforms (not only Windows), because if I understood bpo-427345 correctly, it's really there to bypass a non-standard IE behavior (which appends trailing '\r\n'), and doesn't depend on the platform.
neologix commented on Aug 2, 2013
neologixmannequin
MannequinAuthor
More actions
Marking bpo-10496 as a dependency (since it could prevent Python from running with low level privileges).
Since CGIHTTPRequestHandler is being removed in 3.15, I think this should be closed. However, the author mentions a security issue with the current code, making it a possible bug fix we still want to land.
There’s one important rule: if you invoke an external program (via os.system(), os.popen() or other functions with similar functionality), make very sure you don’t pass arbitrary strings received from the client to the shell. This is a well-known security hole whereby clever hackers anywhere on the web can exploit a gullible CGI script to invoke arbitrary shell commands. Even parts of the URL or field names cannot be trusted, since the request doesn’t have to come from your form!
This note is for the CGI module that was already removed. Now, for the handler, we're already in the a test server module which says:
I don't think it's worth fixing 3.9 to 3.14 as we'll eventually throw away this kind of code. I however agree that the open file descriptors are inherited by the CGI script but I think it's more a "non-security-issue" here. Indeed, expecting Python to execute a CGI script also means expecting the script to be trusted (we don't guarantee that we would protect the user against malicious scripts; in addition, we already warn the user by saying we implement basic security checks).
I will take the blame if something should happen so I'll close this issue as "wont fix". If you're concerned with security, don't use CGI and don't use http.server which is not meant for production use.
Activity
neologix commentedon Jan 12, 2013
On Unix, CGIHTTPRequestHandler.run_cgi() uses the following code to run a CGI script:
"""
pid = os.fork()
[...]
# Child
try:
try:
os.setuid(nobody)
except OSError:
pass
os.dup2(self.rfile.fileno(), 0)
os.dup2(self.wfile.fileno(), 1)
os.execve(scriptfile, args, env)
"""
It's basically reimplementing subprocess.Popen, with a potential securiy issue: open file descriptors are not closed before exec, which means that the CGI script - which is run as 'nobody' on Unix to reduce its priviledges - can inherit open sockets or files (unless they're close-on-exec)...
The attached patch rewrites run_cgi() to use subprocess on all platorms.
I'm not at all familiar with CGI, so I don't guarantee it's correct, but the regression test test_httpservers passes on Linux.
It leads to cleaner and safer code, so if someone with some httpsever/CGI background could review it, it would be great.
neologix commentedon May 4, 2013
The latest version of the patch passes on Linux, OpenIndiana and Windows.
Note that I did apply the select()-hack on all platforms (not only Windows), because if I understood bpo-427345 correctly, it's really there to bypass a non-standard IE behavior (which appends trailing '\r\n'), and doesn't depend on the platform.
neologix commentedon Aug 2, 2013
Marking bpo-10496 as a dependency (since it could prevent Python from running with low level privileges).
devdanzin commentedon Sep 17, 2025
Since
CGIHTTPRequestHandleris being removed in 3.15, I think this should be closed. However, the author mentions a security issue with the current code, making it a possible bug fix we still want to land.picnixz commentedon Sep 17, 2025
CGI is already a bad thing when it comes to security, see the note https://docs.python.org/3.12/library/cgi.html#caring-about-security:
This note is for the CGI module that was already removed. Now, for the handler, we're already in the a test server module which says:
I don't think it's worth fixing 3.9 to 3.14 as we'll eventually throw away this kind of code. I however agree that the open file descriptors are inherited by the CGI script but I think it's more a "non-security-issue" here. Indeed, expecting Python to execute a CGI script also means expecting the script to be trusted (we don't guarantee that we would protect the user against malicious scripts; in addition, we already warn the user by saying we implement basic security checks).
I will take the blame if something should happen so I'll close this issue as "wont fix". If you're concerned with security, don't use CGI and don't use
http.serverwhich is not meant for production use.