
Httpoxy – A CGI application vulnerability - omribahumi
https://httpoxy.org/
======
FooBarWidget
Phusion Passenger author here. Ruby and Python apps deployed through Passenger
are _not_ vulnerable to this issue, despite Rack and WSGI using CGI-style
names. That's because Passenger does not actually set OS environment
variables. It merely passes a hash table/dictionary to the application with
CGI-style keys.

~~~
buren
I must say I really appreciate your hard work FooBarWidget. It seems, to me,
that anytime something like this gets brought up, you've already
addressed/fixed the problem or never even had it in the first place.

I've deployed a few large apps using Phusion Passenger, that years later are
still running with incredible stability. Thank you!

------
discreditable
Another fancy bug website for the list!
[https://github.com/KeenRivals/Bugsite-
Index](https://github.com/KeenRivals/Bugsite-Index)

------
peterwwillis
Perl CGI applications using Taint mode would be unaffected (unless they
intentionally break the tainted variables). I've always wondered why other
languages never implemented a similar "security" feature.
[http://perldoc.perl.org/perlsec.html#Taint-
mode](http://perldoc.perl.org/perlsec.html#Taint-mode)

~~~
james2vegas
libwww-perl has been unaffected since 2001

------
zalmoxes
[https://groups.google.com/forum/m/#!topic/golang-
announce/7J...](https://groups.google.com/forum/m/#!topic/golang-
announce/7JTsd70ZAT0)

1.6.3 will include
[https://github.com/golang/go/commit/fad2bbdc6a686a20174d2e73...](https://github.com/golang/go/commit/fad2bbdc6a686a20174d2e73cf78f1659722bb39)
in addition to the security fix.

~~~
0x0
That's pretty crazy assembly syntax... It looks like "AX" actually references
"EAX" (in 32bit mode) and "RAX" (in 64bit mode), so neither Intel nor AT&T
syntax. Wonder when we'll see the first crypto bug in ported code that mixed
up AX/EAX/RAX...

~~~
masklinn
> That's pretty crazy assembly syntax... It looks like "AX" actually
> references "EAX" (in 32bit mode) and "RAX" (in 64bit mode), so neither Intel
> nor AT&T syntax.

Yeah it's plan9 assembly which is its own thing (just as plan9 "C" was its own
thing): [http://plan9.bell-labs.com/sys/doc/asm.html](http://plan9.bell-
labs.com/sys/doc/asm.html)

~~~
pmalynin
AX, is just the lower 16 bits of EAX, so all correct. This is GAS / AT&T
syntax

~~~
a1k0n
From the context it's obvious that 0x0 is right. AX must be 32 bits (or 64
bits) wide.

[https://github.com/golang/go/blob/fad2bbdc6a686a20174d2e73cf...](https://github.com/golang/go/blob/fad2bbdc6a686a20174d2e73cf78f1659722bb39/src/runtime/sys_darwin_386.s)

------
spriggan3
> RFC 3875 (CGI) puts the HTTP Proxy header from a request into the
> environment variables as HTTP_PROXY

I don't get it, so if I use CGI, and from my code, I query the env variable
named 'HTTP_PROXY' , I will get what was set by the request header PROXY and
not an environment variable 'HTTP_PROXY' as defined by the system the cgi
executable is running on ?

edit :

I looked at CGI

[https://en.wikipedia.org/wiki/Common_Gateway_Interface](https://en.wikipedia.org/wiki/Common_Gateway_Interface)

I don't understand why this protocol just doesn't pass informations as an
argument for the cgi script, why does it have to use environment variables ?

~~~
pfg
If your question is regarding the precedence of the Proxy header vs. an
environment variable, I'm not sure which of the two would win, but even if
it's the latter, anyone who doesn't set it (which is probably the majority)
would still be vulnerable.

~~~
mwpmaybe
CGI implementations will take the value of the Proxy header and clobber
whatever might have originally been set in the environment at HTTP_PROXY.

------
andrewsomething
A good non-technical explainer: [https://medium.com/@nzdominic/what-is-
httpoxy-65a33a8a1f4d#....](https://medium.com/@nzdominic/what-is-
httpoxy-65a33a8a1f4d#.qqum4q5qa)

~~~
vbernat
It says that API requests using TLS are not vulnerable. However, many
applications won't do the appropriate certificate checking. If HTTP_PROXY is
set to a mitm proxy, it can succeed.

~~~
kpcyrd
The reason why they aren't affected is that you need to set HTTPS_PROXY for
[https://](https://)

~~~
lucb1e
I could imagine not all applications doing that, though.

------
jedisct1
Same vulnerability as [https://marc.info/?l=apache-httpd-
dev&m=142277799425452&w=2](https://marc.info/?l=apache-httpd-
dev&m=142277799425452&w=2)

~~~
m4r71n
You can go even further back to 2001 when this was first noticed:

[http://www.nntp.perl.org/group/perl.libwww/2001/03/msg2249.h...](http://www.nntp.perl.org/group/perl.libwww/2001/03/msg2249.html)

------
bdcravens
WPEngine with a not-so reassuring response: "We're aware of it, but no posts
have been made thus far. We will update our blog or email customers if we feel
that there's anything to be concerned about."

(To be fair, this was probably a low-level support engineer, so probably not
that "official" of a response)

------
ungzd
I always wondered why proxy configuration env variable is usually http_proxy,
not HTTP_PROXY, despite env variables are usually uppercase. It made me clear
why.

Moreover, curl has http_proxy, but also HTTPS_PROXY, FTP_PROXY, ..._PROXY,
ALL_PROXY and NO_PROXY.

~~~
nzdominic
Yeah. But the really interesting thing for me was seeing that when Curl
originally fixed it in 2001, they admitted the fix might not work for "Windows
NT" (where environment variables are case-insensitive).

From our testing, we could get getenv in mod_php to return HTTP_PROXY when you
ask for getenv('http_proxy') (seems to happen in the apr stuff?) - but that
didn't affect PHP's libcurl extension, which made it a whole lot less
interesting.

But yeah, if you're running curl itself under CGI with case-insensitive env
vars you might still be in trouble.

------
DasIch
The real lesson here is that environment variables can't be blindly trusted
and that they can be controlled by an attacker unless proven otherwise. They
should be treated as untrusted input that needs to be validated.

If you start a new process, always be explicit about the environment variables
you want to pass on. Don't just let the subprocess inherit your environment
variables.

If you write a library, do not rely on environment variables unless the user
of the library has explicitly opted-in to that.

~~~
omribahumi
CGI prefixes environment variables with "HTTP_" (for HTTP headers), the
problem is this prefix is not unique.

------
orf
Hah, I've found that on my development machine I have to set `http_proxy`,
`HTTP_PROXY`, `https_proxy` _and_ `HTTPS_PROXY` for everything to work right.

This issue is pretty bad though.

------
cperciva
Somewhat related, but not security-related: Quite a few HTTP libraries take
the HTTP_USER_AGENT environment variable and insert it as the User-Agent
header on outgoing requests. When used in a CGI script, this results in the
upstream User-Agent header being forwarded, which is probably not what was
intended.

------
vfaronov
This must be the most elegant vulnerability I've seen in ages. It almost feels
like the pieces are interacting as designed. You politely ask the server to
use a proxy -- and it does!

------
tedchs
An extra problem here is many app-embedded HTTP clients are configured to
ignore HTTPS certificate validation.

~~~
snikch
Not sure this is an issue as you don't make http requests TO the app.

------
mrb
Off-topic but this site should enable gzip encoding for CSS; this would save
83% on the 113 kB main.css…

~~~
nilved
How on Earth does somebody even have 113 KB of CSS?

~~~
gkya
I removed the stylesheed from devtools, and the site was way more readable,
and basically the same in terms of organisation.

~~~
jonny_eh
How do you remove an asset file for a web page via Chrome dev tools?

~~~
nilved
Deleting the `link` tag is one way to do it.

