Issue7250
Created on 2009-11-02 07:34 by snprbob86, last changed 2009-11-05 15:39 by pje.
| Messages (8) | |||
|---|---|---|---|
| msg94819 - (view) | Author: Brandon Bloom (snprbob86) | Date: 2009-11-02 07:34 | |
This issue came up while doing Google App Engine development. Apparently the default wsgi handler logic is to cache os.environ into os_environ at import time. This is reasonable behavior for wsgi, but when using cgi, this is a serious security hole which leaks information between requests. See this related bug at GAE: http://code.google.com/p/googleappengine/issues/detail? id=2040&q=cookies%20dev_appserver.py&colspec=ID%20Type%20Status%20Priority %20Stars%20Owner%20Summary%20Log%20Component |
|||
| msg94867 - (view) | Author: Phillip J. Eby (pje) | Date: 2009-11-03 19:05 | |
This is not an issue with CGI, but an issue with using an inappropriate WSGI handler for a long-running process environment that only emulates CGI. That is, in a true CGI environment, there can't be *multiple* requests made to CGIHandler, and so it can't leak. In "normal" (i.e. pre-GAE) long-running web environments, os.environ would not contain any request information, only the process startup environment. This limitation of CGIHandler should be better documented, but it's a natural consequence of its design. The os_environ and base_environ variables are provided so that subclasses with specialized needs can handle them differently, and GAE is definitely a specialized need. If someone wants to provide a GAEHandler class, great; otherwise, the documented way to run a WSGI app under GAE is the google.appengine.ext.webapp.util.run_wsgi_app function. |
|||
| msg94870 - (view) | Author: Brandon Bloom (snprbob86) | Date: 2009-11-03 20:58 | |
> That is, in a true CGI environment, there can't be *multiple* requests > made to CGIHandler, and so it can't leak. In "normal" (i.e. pre-GAE) > long-running web environments, os.environ would not contain any request > information, only the process startup environment. That's fair. In this case the CGIHandler should raise an exception on subsequent requests to prevent this programming error. > If someone wants to provide a GAEHandler class, great; otherwise, the > documented way to run a WSGI app under GAE is the > google.appengine.ext.webapp.util.run_wsgi_app function. I'm not sure if run_wsgi_app was available right from the start, as some early tutorials and samples show using CGIHandler. That's how we ran into this issue. |
|||
| msg94871 - (view) | Author: Phillip J. Eby (pje) | Date: 2009-11-03 21:13 | |
Hm. In retrospect, CGIHandler should probably just set os_environ to an empty dictionary in its class body (thereby not using the cached environ), and this would then work correctly for repeated uses. This would be a clean bugfix and wouldn't affect behavior for any existing uses of CGIHandler that weren't already worse broken than the GAE case. ;-) |
|||
| msg94880 - (view) | Author: Brandon Bloom (snprbob86) | Date: 2009-11-04 07:14 | |
> Hm. In retrospect, CGIHandler should probably just set os_environ to an > empty dictionary in its class body (thereby not using the cached > environ), and this would then work correctly for repeated uses. > > This would be a clean bugfix and wouldn't affect behavior for any > existing uses of CGIHandler that weren't already worse broken than the > GAE case. ;-) Yup, rock on with that :-) |
|||
| msg94893 - (view) | Author: Phillip J. Eby (pje) | Date: 2009-11-04 16:43 | |
I've forwarded the suggested fix to the GAE team; it is to add this line:
os_environ = {} # Handle GAE and other multi-run CGI use cases
to the class body of CGIHandler. This should also be done in the Python
stdlib.
Btw, this fix can also be applied as a monkeypatch, by simply doing
'CGIHandler.os_environ = {}' before using CGIHandler.
|
|||
| msg94924 - (view) | Author: Brandon Bloom (snprbob86) | Date: 2009-11-05 10:40 | |
> I've forwarded the suggested fix to the GAE team; it is to add this line:
>
> os_environ = {} # Handle GAE and other multi-run CGI use cases
>
> to the class body of CGIHandler. This should also be done in the Python
> stdlib.
I don't think that works. This still shares a common os_environ across
requests. You need to clear the dictionary after every request.
|
|||
| msg94934 - (view) | Author: Phillip J. Eby (pje) | Date: 2009-11-05 15:39 | |
The os_environ attribute is only used in one place; this line: env = self.environ = self.os_environ.copy() So, nothing is shared. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2009-11-05 15:39:49 | pje | set | messages: + msg94934 |
| 2009-11-05 10:40:30 | snprbob86 | set | messages: + msg94924 |
| 2009-11-04 16:43:32 | pje | set | keywords:
+ patch, easy, 26backport messages: + msg94893 |
| 2009-11-04 07:14:29 | snprbob86 | set | messages: + msg94880 |
| 2009-11-03 21:13:55 | pje | set | messages: + msg94871 |
| 2009-11-03 20:58:14 | snprbob86 | set | messages: + msg94870 |
| 2009-11-03 19:05:17 | pje | set | messages: + msg94867 |
| 2009-11-02 23:20:11 | pitrou | set | priority: high assignee: pje nosy: + pje versions: + Python 2.6, Python 3.1, Python 2.7, Python 3.2, - Python 2.5 |
| 2009-11-02 07:34:03 | snprbob86 | create | |