[Web-SIG] WSGI 2.0 Round 2: requirements and call for interest
Armin Ronacher
armin.ronacher at active-4.com
Tue Jan 5 06:50:41 EST 2016
Hi,
I just want to reply to this because I think many people seem to be
missing why things are done in a certain way. Especially if the appear
to be odd.
On 05/01/2016 12:26, Cory Benfield wrote:
> 1. WSGI is prone to header injection vulnerabilities issues by
> designdue to the conversion of HTTP headers to CGI-style environment
> variables: if the server doesn’t specifically prevent it, X-Foo and
> X_Foo both become HTTP_X_Foo. I don’t believe it’s a good choice to
> destructively encode headers, expect applications to undo the damage
> somehow, and introduce security vulnerabilities in the process. If
> mimicking CGI is still considered a must-have — 1% of current Python web
> programmers may have heard about it, most of them from PEP 3333 — then
> that burden should be pushed onto the server, not the application.
Headers always will have to be encoded destructively if you want any
form of generic processing. We need header joining, we need to
normalize the keys already at least to the extend of the HTTP
specification. I'm happy to not perform the conversion of dashes to
underscores but you will work in environments where this conversion was
already done so the spec will need to deal with that case anyways.
The WSGI spec currently also does not sufficiently explain how to join
headers. In particular the cookie header was written without header
joining in mind which is why it needs to be joined differently than all
other headers. Header joining also comes up as a big topic in HTTP 2
so the spec will need to cover this.
> 2. More generally, I fail to see how mixing HTTP headers,
> server-related inputs, and environment variables in a dict adds
> values. It prevents iterating on each collection separately. It only
> makes sense if not offering more features than CGI is a design goal;
> in that case, this discussion doesn’t serve a purpose anyway. It
> would be nicer and possibly more secure if the application received
> separately:
I think this is largely a nice to have, not something that has any
overall benefits. I rather just clean up the actual stupid things such
as CONTENT_TYPE and CONTENT_LENGTH which cause a lot more real world
friction than just the names of keys in general. This really should not
turn into meaningless bikeshedding about what information should be
called. Also consider how much code out there already assumes CGI/WSGI
variables so any move off that really should have good reasons or we all
will just waste enormous amounts just to transpose between the two
representations.
> a. Configuration information, which servers could read from
> environment variables by default for backwards compatibility, but could
> also get through more secure channels and restrict to what the
> application needs in order to better isolate it from the entire OS.
What WSGI traditionally lacked was a setup phase where data could be
passed to the application that was server specific but not request
bound. For instance there is no reason an application cannot get hold
of wsgi.errors before a request comes in. I would like to see this
fixed in a new specification.
> 3. Stop pretending that HTTP is a unicode protocol, or at least stop
> ignoring reality when doing so. WSGI enforces ISO-8859-1-decoded str
> objects in the environ, which is just wrong. It’s all the more a
> surprising choice since this change was driven by Python 3, that UTF-8
> is the correct choice, and that Python 3 defaults to UTF-8. Django has
> to re-encode and re-decode before doing anything with HTTP headers:
I agree with this but you will have to have that fight with others. I
said many times before that values should never have been unicode values
in the first place but certain decisions in the Python 3 standard
library at the time prevented that. In particular until 3.2 or so it
was impossible to parse byte URLs.
> 5. Improve request / response length handling and connection closure.
> Armin and Graham have talked about in the past and know the topic
> better than I do. There’s also a rejected PEP by Armin which made
> sense to me.
I think last time I discussed that with Graham it was not clear what the
solution is in the context of WSGI. The idea that there is a
content-length is laughable in the context of a real application where
the server is performing conversions on the input and output stream. We
would need many more than just one content length and an automatically
terminated input stream.
However at that point you will quickly realize that you can't have it
both ways and you either have a WSGI like protocol, or raw access to
sockets but certainly not both. This topic has caused a lot of
bikeshedding in the past and I fail to see how it will be differently
this time.
My current thinking is that the most realistic approach to most of those
problems will be the concept of framing on both the input and output
side. That's somewhat compatible with both chunked transports well as
websockets. But if we do go down this road we will most likely have to
standardize on a library that implements WSGI as the complexity of
dealing with this sort of stuff is significantly higher than what we had
to do in the past.
Regards,
Armin
More information about the Web-SIG
mailing list