websecurity@lists.webappsec.org

The Web Security Mailing List

View all threads

A technique for bypassing request header restriction of XMLHttpRequest

KE
Kousuke Ebihara
Thu, Jan 5, 2012 12:13 PM

Hi,

Do you know that Apache HTTP Server and Lighttpd replace non-alnum characters with underscore in name of environment variables?

This might be useful to bypass restrictions of XMLHttpRequest.

Here is a simple CGI script to test server behavior::

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os

print "Content-Type: text/plain\n";

for k, v in sorted(os.environ.items()):
     print "%s: %s" % (k, v)

And execute this script via Apache::

$ telnet localhost 80
GET /~co3k/envs.cgi.py HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.1 200 OK
Date: Wed, 23 Nov 2011 10:30:53 GMT
Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch
Connection: close
Content-Type: text/plain

HTTP_X_DOT: Hello
HTTP_X_NORMAL: Hello
HTTP_X_UNDER: Hello

Then, via Lighttpd::

$ telnet localhost 8037
GET /envs.cgi.py HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.0 200 OK
Content-Type: text/plain
Connection: close
Date: Wed, 23 Nov 2011 10:43:12 GMT
Server: lighttpd/1.4.28

HTTP_X_DOT: Hello
HTTP_X_NORMAL: Hello
HTTP_X_UNDER: Hello

But the case of Nginx::

$ telnet localhost 8080
GET /env/ HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.1 200 OK
Server: nginx/1.0.9
Date: Wed, 23 Nov 2011 10:57:07 GMT
Content-Type: text/plain
Connection: close

HTTP_X_NORMAL: Hello

Well, as you know, some XMLHttpRequest implementations deny sending some request headers via XMLHttpRequest.

(See also: http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)

You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via Firefox's XMLHttpRequest, but you can send Accept_Charset, Accept.Encoding, UserAgent and etc. CGI script may trust UserAgent header value via "HTTP_USER_AGENT" environment variable.

I've found a vulnerability in the Japanese mobile phone by using this technique. But that vulnerability is caused by unusual custom of Japanese mobile world.

So I want to know more universal threats by using this technique. Do you have some ideas?

Thanks,

--
Kousuke Ebihara kousuke@co3k.org
http://co3k.org/

Hi, Do you know that Apache HTTP Server and Lighttpd replace non-alnum characters with underscore in name of environment variables? This might be useful to bypass restrictions of XMLHttpRequest. Here is a simple CGI script to test server behavior:: #!/usr/bin/env python # -*- coding: UTF-8 -*- import os print "Content-Type: text/plain\n"; for k, v in sorted(os.environ.items()): print "%s: %s" % (k, v) And execute this script via Apache:: $ telnet localhost 80 GET /~co3k/envs.cgi.py HTTP/1.0 X-Normal: Hello X_Under: Hello X.Dot: Hello HTTP/1.1 200 OK Date: Wed, 23 Nov 2011 10:30:53 GMT Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch Connection: close Content-Type: text/plain HTTP_X_DOT: Hello HTTP_X_NORMAL: Hello HTTP_X_UNDER: Hello Then, via Lighttpd:: $ telnet localhost 8037 GET /envs.cgi.py HTTP/1.0 X-Normal: Hello X_Under: Hello X.Dot: Hello HTTP/1.0 200 OK Content-Type: text/plain Connection: close Date: Wed, 23 Nov 2011 10:43:12 GMT Server: lighttpd/1.4.28 HTTP_X_DOT: Hello HTTP_X_NORMAL: Hello HTTP_X_UNDER: Hello But the case of Nginx:: $ telnet localhost 8080 GET /env/ HTTP/1.0 X-Normal: Hello X_Under: Hello X.Dot: Hello HTTP/1.1 200 OK Server: nginx/1.0.9 Date: Wed, 23 Nov 2011 10:57:07 GMT Content-Type: text/plain Connection: close HTTP_X_NORMAL: Hello Well, as you know, some XMLHttpRequest implementations deny sending some request headers via XMLHttpRequest. (See also: http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via Firefox's XMLHttpRequest, but you can send Accept_Charset, Accept.Encoding, User*Agent and etc. CGI script may trust User*Agent header value via "HTTP_USER_AGENT" environment variable. I've found a vulnerability in the Japanese mobile phone by using this technique. But that vulnerability is caused by unusual custom of Japanese mobile world. So I want to know more universal threats by using this technique. Do you have some ideas? Thanks, -- Kousuke Ebihara <kousuke@co3k.org> http://co3k.org/
PS
Prasad Shenoy
Thu, Jan 5, 2012 11:03 PM

Nice. Would it make sense if I say the success of this might solely depend
on the order of the spoofed header? or that is obvious?

Different browsers have different order in which the request headers are
stacked. FF 8.0.1 added the actual system User-Agent header before the
custom request headers (User%Agent - created by XMLHttpRequest object).
Chrome and IE 7 both added the custom header before the actual header.

I did not see any ordering preferences in the RFCs.

[ ~ Prasad |  @prasadshenoy  ~]

On Thu, Jan 5, 2012 at 7:13 AM, Kousuke Ebihara kousuke@co3k.org wrote:

Hi,

Do you know that Apache HTTP Server and Lighttpd replace non-alnum
characters with underscore in name of environment variables?

This might be useful to bypass restrictions of XMLHttpRequest.

Here is a simple CGI script to test server behavior::

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os

print "Content-Type: text/plain\n";

for k, v in sorted(os.environ.items()):
     print "%s: %s" % (k, v)

And execute this script via Apache::

$ telnet localhost 80
GET /~co3k/envs.cgi.py HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.1 200 OK
Date: Wed, 23 Nov 2011 10:30:53 GMT
Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch
Connection: close
Content-Type: text/plain

HTTP_X_DOT: Hello
HTTP_X_NORMAL: Hello
HTTP_X_UNDER: Hello

Then, via Lighttpd::

$ telnet localhost 8037
GET /envs.cgi.py HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.0 200 OK
Content-Type: text/plain
Connection: close
Date: Wed, 23 Nov 2011 10:43:12 GMT
Server: lighttpd/1.4.28

HTTP_X_DOT: Hello
HTTP_X_NORMAL: Hello
HTTP_X_UNDER: Hello

But the case of Nginx::

$ telnet localhost 8080
GET /env/ HTTP/1.0
X-Normal: Hello
X_Under: Hello
X.Dot: Hello

HTTP/1.1 200 OK
Server: nginx/1.0.9
Date: Wed, 23 Nov 2011 10:57:07 GMT
Content-Type: text/plain
Connection: close

HTTP_X_NORMAL: Hello

Well, as you know, some XMLHttpRequest implementations deny sending some
request headers via XMLHttpRequest.

(See also:
http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest
)

You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via
Firefox's XMLHttpRequest, but you can send Accept_Charset, Accept.Encoding,
UserAgent and etc. CGI script may trust UserAgent header value via
"HTTP_USER_AGENT" environment variable.

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

So I want to know more universal threats by using this technique. Do you
have some ideas?

Thanks,

--
Kousuke Ebihara kousuke@co3k.org
http://co3k.org/


The Web Security Mailing List

WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss

Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA

WASC on Twitter
http://twitter.com/wascupdates

websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org

Nice. Would it make sense if I say the success of this might solely depend on the order of the spoofed header? or that is obvious? Different browsers have different order in which the request headers are stacked. FF 8.0.1 added the actual system User-Agent header before the custom request headers (User%Agent - created by XMLHttpRequest object). Chrome and IE 7 both added the custom header before the actual header. I did not see any ordering preferences in the RFCs. [ ~ Prasad | @prasadshenoy ~] On Thu, Jan 5, 2012 at 7:13 AM, Kousuke Ebihara <kousuke@co3k.org> wrote: > Hi, > > Do you know that Apache HTTP Server and Lighttpd replace non-alnum > characters with underscore in name of environment variables? > > This might be useful to bypass restrictions of XMLHttpRequest. > > Here is a simple CGI script to test server behavior:: > > #!/usr/bin/env python > # -*- coding: UTF-8 -*- > > import os > > print "Content-Type: text/plain\n"; > > for k, v in sorted(os.environ.items()): > print "%s: %s" % (k, v) > > And execute this script via Apache:: > > $ telnet localhost 80 > GET /~co3k/envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Date: Wed, 23 Nov 2011 10:30:53 GMT > Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch > Connection: close > Content-Type: text/plain > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > Then, via Lighttpd:: > > $ telnet localhost 8037 > GET /envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.0 200 OK > Content-Type: text/plain > Connection: close > Date: Wed, 23 Nov 2011 10:43:12 GMT > Server: lighttpd/1.4.28 > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > But the case of Nginx:: > > $ telnet localhost 8080 > GET /env/ HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Server: nginx/1.0.9 > Date: Wed, 23 Nov 2011 10:57:07 GMT > Content-Type: text/plain > Connection: close > > HTTP_X_NORMAL: Hello > > Well, as you know, some XMLHttpRequest implementations deny sending some > request headers via XMLHttpRequest. > > (See also: > http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest > ) > > You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via > Firefox's XMLHttpRequest, but you can send Accept_Charset, Accept.Encoding, > User*Agent and etc. CGI script may trust User*Agent header value via > "HTTP_USER_AGENT" environment variable. > > I've found a vulnerability in the Japanese mobile phone by using this > technique. But that vulnerability is caused by unusual custom of Japanese > mobile world. > > So I want to know more universal threats by using this technique. Do you > have some ideas? > > Thanks, > > -- > Kousuke Ebihara <kousuke@co3k.org> > http://co3k.org/ > > _______________________________________________ > The Web Security Mailing List > > WebSecurity RSS Feed > http://www.webappsec.org/rss/websecurity.rss > > Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA > > WASC on Twitter > http://twitter.com/wascupdates > > websecurity@lists.webappsec.org > http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org >
HB
Hill, Brad
Thu, Jan 5, 2012 11:17 PM

This is an artifact of the mismatch between the character set available for Unix shell environment variables and those legal in RFC 822 headers as used by HTTP.  The equivalence between at least - and _ is documented in RFC 3875.  http://tools.ietf.org/html/rfc3875#section-4.1.18

'Meta-variables with names beginning with "HTTP_" contain values read
from the client request header fields, if the protocol used is HTTP.
The HTTP header field name is converted to upper case, has all
occurrences of "-" replaced with "" and has "HTTP" prepended to
give the meta-variable name.'

That RFC is from 2004, but documents practices that began in 1993.

So I would expect this bug to be present on all CGI-style applications, and absent in frameworks that provide a better object mapping to HTTP values, e.g. servlets.

Given this is documented and standardized behavior, it seems that the XHR spec should be updated to compare at least "_" and possibly other characters not valid in Unix shell variables, as equivalent to "-" when blacklisting custom headers.

Brad Hill
Sr. MTS, Internet Standards and Governance
PayPal Information Risk Management
cell: 206.245.7844 / skype: hillbrad
email: bhill@paypal-inc.com

-----Original Message-----
From: websecurity-bounces@lists.webappsec.org [mailto:websecurity-
bounces@lists.webappsec.org] On Behalf Of Kousuke Ebihara
Sent: Thursday, January 05, 2012 4:13 AM
To: websecurity@lists.webappsec.org
Subject: [WEB SECURITY] A technique for bypassing request header
restriction of XMLHttpRequest

Hi,

Do you know that Apache HTTP Server and Lighttpd replace non-alnum
characters with underscore in name of environment variables?

This might be useful to bypass restrictions of XMLHttpRequest.

Here is a simple CGI script to test server behavior::

 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-

 import os

 print "Content-Type: text/plain\n";

 for k, v in sorted(os.environ.items()):
      print "%s: %s" % (k, v)

And execute this script via Apache::

 $ telnet localhost 80
 GET /~co3k/envs.cgi.py HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.1 200 OK
 Date: Wed, 23 Nov 2011 10:30:53 GMT
 Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch
 Connection: close
 Content-Type: text/plain

 HTTP_X_DOT: Hello
 HTTP_X_NORMAL: Hello
 HTTP_X_UNDER: Hello

Then, via Lighttpd::

 $ telnet localhost 8037
 GET /envs.cgi.py HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.0 200 OK
 Content-Type: text/plain
 Connection: close
 Date: Wed, 23 Nov 2011 10:43:12 GMT
 Server: lighttpd/1.4.28

 HTTP_X_DOT: Hello
 HTTP_X_NORMAL: Hello
 HTTP_X_UNDER: Hello

But the case of Nginx::

 $ telnet localhost 8080
 GET /env/ HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.1 200 OK
 Server: nginx/1.0.9
 Date: Wed, 23 Nov 2011 10:57:07 GMT
 Content-Type: text/plain
 Connection: close

 HTTP_X_NORMAL: Hello

Well, as you know, some XMLHttpRequest implementations deny sending
some request headers via XMLHttpRequest.

(See also: http://code.google.com/p/browsersec/wiki/Part2#Same-
origin_policy_for_XMLHttpRequest)

You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via
Firefox's XMLHttpRequest, but you can send Accept_Charset,
Accept.Encoding, UserAgent and etc. CGI script may trust UserAgent
header value via "HTTP_USER_AGENT" environment variable.

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

So I want to know more universal threats by using this technique. Do you
have some ideas?

Thanks,

--
Kousuke Ebihara kousuke@co3k.org
http://co3k.org/


The Web Security Mailing List

WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss

Join WASC on LinkedIn
http://www.linkedin.com/e/gis/83336/4B20E4374DBA

WASC on Twitter
http://twitter.com/wascupdates

websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.or
g

This is an artifact of the mismatch between the character set available for Unix shell environment variables and those legal in RFC 822 headers as used by HTTP. The equivalence between at least - and _ is documented in RFC 3875. http://tools.ietf.org/html/rfc3875#section-4.1.18 'Meta-variables with names beginning with "HTTP_" contain values read from the client request header fields, if the protocol used is HTTP. The HTTP header field name is converted to upper case, has all occurrences of "-" replaced with "_" and has "HTTP_" prepended to give the meta-variable name.' That RFC is from 2004, but documents practices that began in 1993. So I would expect this bug to be present on all CGI-style applications, and absent in frameworks that provide a better object mapping to HTTP values, e.g. servlets. Given this is documented and standardized behavior, it seems that the XHR spec should be updated to compare at least "_" and possibly other characters not valid in Unix shell variables, as equivalent to "-" when blacklisting custom headers. Brad Hill Sr. MTS, Internet Standards and Governance PayPal Information Risk Management cell: 206.245.7844 / skype: hillbrad email: bhill@paypal-inc.com > -----Original Message----- > From: websecurity-bounces@lists.webappsec.org [mailto:websecurity- > bounces@lists.webappsec.org] On Behalf Of Kousuke Ebihara > Sent: Thursday, January 05, 2012 4:13 AM > To: websecurity@lists.webappsec.org > Subject: [WEB SECURITY] A technique for bypassing request header > restriction of XMLHttpRequest > > Hi, > > Do you know that Apache HTTP Server and Lighttpd replace non-alnum > characters with underscore in name of environment variables? > > This might be useful to bypass restrictions of XMLHttpRequest. > > Here is a simple CGI script to test server behavior:: > > #!/usr/bin/env python > # -*- coding: UTF-8 -*- > > import os > > print "Content-Type: text/plain\n"; > > for k, v in sorted(os.environ.items()): > print "%s: %s" % (k, v) > > And execute this script via Apache:: > > $ telnet localhost 80 > GET /~co3k/envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Date: Wed, 23 Nov 2011 10:30:53 GMT > Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch > Connection: close > Content-Type: text/plain > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > Then, via Lighttpd:: > > $ telnet localhost 8037 > GET /envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.0 200 OK > Content-Type: text/plain > Connection: close > Date: Wed, 23 Nov 2011 10:43:12 GMT > Server: lighttpd/1.4.28 > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > But the case of Nginx:: > > $ telnet localhost 8080 > GET /env/ HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Server: nginx/1.0.9 > Date: Wed, 23 Nov 2011 10:57:07 GMT > Content-Type: text/plain > Connection: close > > HTTP_X_NORMAL: Hello > > Well, as you know, some XMLHttpRequest implementations deny sending > some request headers via XMLHttpRequest. > > (See also: http://code.google.com/p/browsersec/wiki/Part2#Same- > origin_policy_for_XMLHttpRequest) > > You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via > Firefox's XMLHttpRequest, but you can send Accept_Charset, > Accept.Encoding, User*Agent and etc. CGI script may trust User*Agent > header value via "HTTP_USER_AGENT" environment variable. > > I've found a vulnerability in the Japanese mobile phone by using this > technique. But that vulnerability is caused by unusual custom of Japanese > mobile world. > > So I want to know more universal threats by using this technique. Do you > have some ideas? > > Thanks, > > -- > Kousuke Ebihara <kousuke@co3k.org> > http://co3k.org/ > > _______________________________________________ > The Web Security Mailing List > > WebSecurity RSS Feed > http://www.webappsec.org/rss/websecurity.rss > > Join WASC on LinkedIn > http://www.linkedin.com/e/gis/83336/4B20E4374DBA > > WASC on Twitter > http://twitter.com/wascupdates > > websecurity@lists.webappsec.org > http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.or > g
RA
Robert A.
Thu, Jan 5, 2012 11:36 PM

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

What were you able to do?

So I want to know more universal threats by using this technique. Do you
have some ideas?

A couple things come to mind (assuming this works on single word headers which I've been unable to get working)

  1. Modifying headers such as 'Host' to access other virtualhosts on the
    same ip, or breaking weak CSRF protections by modifying the 'Referer' header (http://www.securityfocus.com/archive/1/441014)

  2. Potential shared virtual hosting browser cache poisoning?
    (http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2008-June/003951.html)

  3. Abusing transparent proxies via Host header modification
    (http://www.thesecuritypractice.com/the_security_practice/2010/03/abusing-transparent-proxies-with-flash-presentation-available-paper-update.html)

Regards,

>> I've found a vulnerability in the Japanese mobile phone by using this >> technique. But that vulnerability is caused by unusual custom of Japanese >> mobile world. What were you able to do? >> >> So I want to know more universal threats by using this technique. Do you >> have some ideas? A couple things come to mind (assuming this works on single word headers which I've been unable to get working) 1. Modifying headers such as 'Host' to access other virtualhosts on the same ip, or breaking weak CSRF protections by modifying the 'Referer' header (http://www.securityfocus.com/archive/1/441014) 2. Potential shared virtual hosting browser cache poisoning? (http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2008-June/003951.html) 3. Abusing transparent proxies via Host header modification (http://www.thesecuritypractice.com/the_security_practice/2010/03/abusing-transparent-proxies-with-flash-presentation-available-paper-update.html) Regards, - Robert A. http://www.webappsec.org/ http://www.cgisecurity.com/ http://www.qasec.com/ >> >> Thanks, >> >> -- >> Kousuke Ebihara <kousuke@co3k.org> >> http://co3k.org/ >> >> _______________________________________________ >> The Web Security Mailing List >> >> WebSecurity RSS Feed >> http://www.webappsec.org/rss/websecurity.rss >> >> Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA >> >> WASC on Twitter >> http://twitter.com/wascupdates >> >> websecurity@lists.webappsec.org >> http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org >> >
RA
Robert A.
Fri, Jan 6, 2012 12:22 AM

Actually scratch my last reply.

/me will drink some coffee before hitting the send button next time :)

On Thu, 5 Jan 2012, Robert A. wrote:

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

What were you able to do?

So I want to know more universal threats by using this technique. Do you
have some ideas?

A couple things come to mind (assuming this works on single word headers
which I've been unable to get working)

  1. Modifying headers such as 'Host' to access other virtualhosts on the same
    ip, or breaking weak CSRF protections by modifying the 'Referer' header
    (http://www.securityfocus.com/archive/1/441014)

  2. Potential shared virtual hosting browser cache poisoning?
    (http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2008-June/003951.html)

  3. Abusing transparent proxies via Host header modification
    (http://www.thesecuritypractice.com/the_security_practice/2010/03/abusing-transparent-proxies-with-flash-presentation-available-paper-update.html)

Regards,

Actually scratch my last reply. /me will drink some coffee before hitting the send button next time :) On Thu, 5 Jan 2012, Robert A. wrote: >>> I've found a vulnerability in the Japanese mobile phone by using this >>> technique. But that vulnerability is caused by unusual custom of Japanese >>> mobile world. > > What were you able to do? > >>> >>> So I want to know more universal threats by using this technique. Do you >>> have some ideas? > > A couple things come to mind (assuming this works on single word headers > which I've been unable to get working) > > 1. Modifying headers such as 'Host' to access other virtualhosts on the same > ip, or breaking weak CSRF protections by modifying the 'Referer' header > (http://www.securityfocus.com/archive/1/441014) > > 2. Potential shared virtual hosting browser cache poisoning? > (http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2008-June/003951.html) > > 3. Abusing transparent proxies via Host header modification > (http://www.thesecuritypractice.com/the_security_practice/2010/03/abusing-transparent-proxies-with-flash-presentation-available-paper-update.html) > > Regards, > - Robert A. > http://www.webappsec.org/ > http://www.cgisecurity.com/ > http://www.qasec.com/ > >>> >>> Thanks, >>> >>> -- >>> Kousuke Ebihara <kousuke@co3k.org> >>> http://co3k.org/ >>> >>> _______________________________________________ >>> The Web Security Mailing List >>> >>> WebSecurity RSS Feed >>> http://www.webappsec.org/rss/websecurity.rss >>> >>> Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA >>> >>> WASC on Twitter >>> http://twitter.com/wascupdates >>> >>> websecurity@lists.webappsec.org >>> http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org >>> >> > > > _______________________________________________ > The Web Security Mailing List > > WebSecurity RSS Feed > http://www.webappsec.org/rss/websecurity.rss > > Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA > > WASC on Twitter > http://twitter.com/wascupdates > > websecurity@lists.webappsec.org > http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org >
A
albinowax@eml.cc
Fri, Jan 6, 2012 12:46 AM

Perhaps it could be combined with the 307 flash header-forging
vulnerability (
http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2011-February/007533.html
) to forge user-agent headers cross domain; some sites use user-agents
as a weak CSRF protection (don't ask). Or another similar but unpatched
vulnerability.

albino

On Thu, Jan 5, 2012, at 09:13 PM, Kousuke Ebihara wrote:

Hi,

Do you know that Apache HTTP Server and Lighttpd replace non-alnum
characters with underscore in name of environment variables?

This might be useful to bypass restrictions of XMLHttpRequest.

Here is a simple CGI script to test server behavior::

 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-

 import os

 print "Content-Type: text/plain\n";

 for k, v in sorted(os.environ.items()):
      print "%s: %s" % (k, v)

And execute this script via Apache::

 $ telnet localhost 80
 GET /~co3k/envs.cgi.py HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.1 200 OK
 Date: Wed, 23 Nov 2011 10:30:53 GMT
 Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch
 Connection: close
 Content-Type: text/plain

 HTTP_X_DOT: Hello
 HTTP_X_NORMAL: Hello
 HTTP_X_UNDER: Hello

Then, via Lighttpd::

 $ telnet localhost 8037
 GET /envs.cgi.py HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.0 200 OK
 Content-Type: text/plain
 Connection: close
 Date: Wed, 23 Nov 2011 10:43:12 GMT
 Server: lighttpd/1.4.28

 HTTP_X_DOT: Hello
 HTTP_X_NORMAL: Hello
 HTTP_X_UNDER: Hello

But the case of Nginx::

 $ telnet localhost 8080
 GET /env/ HTTP/1.0
 X-Normal: Hello
 X_Under: Hello
 X.Dot: Hello

 HTTP/1.1 200 OK
 Server: nginx/1.0.9
 Date: Wed, 23 Nov 2011 10:57:07 GMT
 Content-Type: text/plain
 Connection: close

 HTTP_X_NORMAL: Hello

Well, as you know, some XMLHttpRequest implementations deny sending some
request headers via XMLHttpRequest.

(See also:
http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)

You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via
Firefox's XMLHttpRequest, but you can send Accept_Charset,
Accept.Encoding, UserAgent and etc. CGI script may trust UserAgent
header value via "HTTP_USER_AGENT" environment variable.

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

So I want to know more universal threats by using this technique. Do you
have some ideas?

Thanks,

--
Kousuke Ebihara kousuke@co3k.org
http://co3k.org/


The Web Security Mailing List

WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss

Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA

WASC on Twitter
http://twitter.com/wascupdates

websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org

Perhaps it could be combined with the 307 flash header-forging vulnerability ( http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2011-February/007533.html ) to forge user-agent headers cross domain; some sites use user-agents as a weak CSRF protection (don't ask). Or another similar but unpatched vulnerability. albino On Thu, Jan 5, 2012, at 09:13 PM, Kousuke Ebihara wrote: > Hi, > > Do you know that Apache HTTP Server and Lighttpd replace non-alnum > characters with underscore in name of environment variables? > > This might be useful to bypass restrictions of XMLHttpRequest. > > Here is a simple CGI script to test server behavior:: > > #!/usr/bin/env python > # -*- coding: UTF-8 -*- > > import os > > print "Content-Type: text/plain\n"; > > for k, v in sorted(os.environ.items()): > print "%s: %s" % (k, v) > > And execute this script via Apache:: > > $ telnet localhost 80 > GET /~co3k/envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Date: Wed, 23 Nov 2011 10:30:53 GMT > Server: Apache/2.2.20 (Unix) DAV/2 PHP/5.3.6 with Suhosin-Patch > Connection: close > Content-Type: text/plain > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > Then, via Lighttpd:: > > $ telnet localhost 8037 > GET /envs.cgi.py HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.0 200 OK > Content-Type: text/plain > Connection: close > Date: Wed, 23 Nov 2011 10:43:12 GMT > Server: lighttpd/1.4.28 > > HTTP_X_DOT: Hello > HTTP_X_NORMAL: Hello > HTTP_X_UNDER: Hello > > But the case of Nginx:: > > $ telnet localhost 8080 > GET /env/ HTTP/1.0 > X-Normal: Hello > X_Under: Hello > X.Dot: Hello > > HTTP/1.1 200 OK > Server: nginx/1.0.9 > Date: Wed, 23 Nov 2011 10:57:07 GMT > Content-Type: text/plain > Connection: close > > HTTP_X_NORMAL: Hello > > Well, as you know, some XMLHttpRequest implementations deny sending some > request headers via XMLHttpRequest. > > (See also: > http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) > > You can't send Accept-Charset, Accept-Encoding, User-Agent, and etc via > Firefox's XMLHttpRequest, but you can send Accept_Charset, > Accept.Encoding, User*Agent and etc. CGI script may trust User*Agent > header value via "HTTP_USER_AGENT" environment variable. > > I've found a vulnerability in the Japanese mobile phone by using this > technique. But that vulnerability is caused by unusual custom of Japanese > mobile world. > > So I want to know more universal threats by using this technique. Do you > have some ideas? > > Thanks, > > -- > Kousuke Ebihara <kousuke@co3k.org> > http://co3k.org/ > > _______________________________________________ > The Web Security Mailing List > > WebSecurity RSS Feed > http://www.webappsec.org/rss/websecurity.rss > > Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA > > WASC on Twitter > http://twitter.com/wascupdates > > websecurity@lists.webappsec.org > http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org >
KE
Kousuke Ebihara
Fri, Jan 6, 2012 12:28 PM

I've found a vulnerability in the Japanese mobile phone by using this
technique. But that vulnerability is caused by unusual custom of Japanese
mobile world.

What were you able to do?

Bypass authentication.

Many sites for Japanese feature phone implements weak authentication system which depends on user identifiers in HTTP header (e.g. X-Up-Subno).

The carrier takes measures to prevent spoofing the identifier.

One of them is a restricted XHR in its web browser. The XHR implementation denies sending "X-Up-Subno" and "X_Up_Subno" request header, but it allows "X.Up.Subno" header, so attacker could spoof the user identifier by using this technique.

Of course, authentication by only ID is too bad. However, in Japanese mobile sites, this "authenticate" method is popular for some reasons, so that vulnerability could create real threats.

--
Kousuke Ebihara kousuke@co3k.org
http://co3k.org/

>>> I've found a vulnerability in the Japanese mobile phone by using this >>> technique. But that vulnerability is caused by unusual custom of Japanese >>> mobile world. > > What were you able to do? Bypass authentication. Many sites for Japanese feature phone implements weak authentication system which depends on user identifiers in HTTP header (e.g. X-Up-Subno). The carrier takes measures to prevent spoofing the identifier. One of them is a restricted XHR in its web browser. The XHR implementation denies sending "X-Up-Subno" and "X_Up_Subno" request header, but it allows "X.Up.Subno" header, so attacker could spoof the user identifier by using this technique. Of course, authentication by only ID is too bad. However, in Japanese mobile sites, this "authenticate" method is popular for some reasons, so that vulnerability could create real threats. -- Kousuke Ebihara <kousuke@co3k.org> http://co3k.org/
T
Tim
Fri, Jan 6, 2012 5:08 PM

This is an artifact of the mismatch between the character set available for Unix shell environment variables and those legal in RFC 822 headers as used by HTTP.  The equivalence between at least - and _ is documented in RFC 3875.  http://tools.ietf.org/html/rfc3875#section-4.1.18

Actually, at least in Unix, shell environment variables can have just
about any character, except for perhaps '\x00' and '=' (IIRC...
haven't looked at the storage format in a while).  For example:

$ env 'FOOBAR=BAZ' /bin/sh -c 'set' | grep FOO
FOO
BAR='BAZ'

It's just that most shells restrict the characters you can use to set
these or access them.  For all I know, other scripting languages could
have similar restrictions.  So naturally when defining CGI, someone
felt the need to impose some sort of restrictions on variable names to
be compatible with existing scripting languages, including shell.

As a security guy, I find "squashing" characters down to a single safe
place-holder is always a bad idea, as we see it play out here with
namespace conficts.  A better approach would have been to come up with
an encoding/escaping scheme, or to just reject the names you don't
like up front.  But what is done is done.

When I first read Kousuke's email, I thought to myself that browsers
(in the XMLHttpRequest context) or web servers really ought to reject
those headers that contain '.' and '*', since those can't be valid
names.  As it turns out they are valid, based on the HTTP/1.1 spec.
Relevant excerpts from RFC2616:

   CHAR           = <any US-ASCII character (octets 0 - 127)>

...
CTL            = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
...
token          = 1*<any CHAR except CTLs or separators>
separators    = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
...
message-header = field-name ":" [ field-value ]
field-name    = token
...

Somewhat surprisingly, all of the following are permitted in HTTP
header names:

!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~

So I would expect this bug to be present on all CGI-style applications, and absent in frameworks that provide a better object mapping to HTTP values, e.g. servlets.

I think it could vary widely from framework to framework, what is
squashed, permitted, and rejected.

Given this is documented and standardized behavior, it seems that the XHR spec should be updated to compare at least "_" and possibly other characters not valid in Unix shell variables, as equivalent to "-" when blacklisting custom headers.

I think given the clearly defined HTTP RFC, we're really looking at
age-old insecure practices in interpreting headers on the web server.
There's no reason that headers with permitted special characters
shouldn't be accessible through an appropriate API.  No good reason to
continue squashing and polluting the namespace.

tim

> This is an artifact of the mismatch between the character set available for Unix shell environment variables and those legal in RFC 822 headers as used by HTTP. The equivalence between at least - and _ is documented in RFC 3875. http://tools.ietf.org/html/rfc3875#section-4.1.18 Actually, at least in Unix, shell environment variables can have just about any character, except for perhaps '\x00' and '=' (IIRC... haven't looked at the storage format in a while). For example: $ env 'FOO*BAR=BAZ' /bin/sh -c 'set' | grep FOO FOO*BAR='BAZ' It's just that most shells restrict the characters you can use to set these or access them. For all I know, other scripting languages could have similar restrictions. So naturally when defining CGI, someone felt the need to impose some sort of restrictions on variable names to be compatible with existing scripting languages, including shell. As a security guy, I find "squashing" characters down to a single safe place-holder is always a bad idea, as we see it play out here with namespace conficts. A better approach would have been to come up with an encoding/escaping scheme, or to just reject the names you don't like up front. But what is done is done. When I first read Kousuke's email, I thought to myself that browsers (in the XMLHttpRequest context) or web servers really ought to reject those headers that contain '.' and '*', since those can't be valid names. As it turns out they are valid, based on the HTTP/1.1 spec. Relevant excerpts from RFC2616: CHAR = <any US-ASCII character (octets 0 - 127)> ... CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> ... token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT ... message-header = field-name ":" [ field-value ] field-name = token ... Somewhat surprisingly, all of the following are permitted in HTTP header names: !#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~ > So I would expect this bug to be present on all CGI-style applications, and absent in frameworks that provide a better object mapping to HTTP values, e.g. servlets. I think it could vary widely from framework to framework, what is squashed, permitted, and rejected. > Given this is documented and standardized behavior, it seems that the XHR spec should be updated to compare at least "_" and possibly other characters not valid in Unix shell variables, as equivalent to "-" when blacklisting custom headers. I think given the clearly defined HTTP RFC, we're really looking at age-old insecure practices in interpreting headers on the web server. There's no reason that headers with permitted special characters shouldn't be accessible through an appropriate API. No good reason to continue squashing and polluting the namespace. tim
HB
Hill, Brad
Fri, Jan 6, 2012 5:18 PM

I think given the clearly defined HTTP RFC, we're really looking at age-old
insecure practices in interpreting headers on the web server.
There's no reason that headers with permitted special characters shouldn't
be accessible through an appropriate API.  No good reason to continue
squashing and polluting the namespace.

[Hill, Brad] I would say the opposite.  Given a documented, common practice that, however hacky, has been established for nearly 20 years, there is every reason for a new technology (or at least, relatively new) not to introduce vulnerabilities to a huge and established ecosystem.

I'm not saying XHR should actually coerce non-alphanumeric characters down when sending headers - only that the security checks for banned headers should do this for purposes of pre-flight comparison.  There is an obligation not to introduce new vulnerabilities into existing systems, and the "cost" to long-term compatibility with HTTP is very small: the blacklist becomes a set of simple regexes instead of string literals.

Brad Hill
Co-chair, WebAppSec WG

> I think given the clearly defined HTTP RFC, we're really looking at age-old > insecure practices in interpreting headers on the web server. > There's no reason that headers with permitted special characters shouldn't > be accessible through an appropriate API. No good reason to continue > squashing and polluting the namespace. [Hill, Brad] I would say the opposite. Given a documented, common practice that, however hacky, has been established for nearly 20 years, there is every reason for a new technology (or at least, relatively new) not to introduce vulnerabilities to a huge and established ecosystem. I'm not saying XHR should actually coerce non-alphanumeric characters down when sending headers - only that the security checks for banned headers should do this for purposes of pre-flight comparison. There is an obligation not to introduce new vulnerabilities into existing systems, and the "cost" to long-term compatibility with HTTP is very small: the blacklist becomes a set of simple regexes instead of string literals. Brad Hill Co-chair, WebAppSec WG
T
Tim
Fri, Jan 6, 2012 5:43 PM

[Hill, Brad] I would say the opposite.  Given a documented, common practice that, however hacky, has been established for nearly 20 years, there is every reason for a new technology (or at least, relatively new) not to introduce vulnerabilities to a huge and established ecosystem.

I'm not saying XHR should actually coerce non-alphanumeric characters down when sending headers - only that the security checks for banned headers should do this for purposes of pre-flight comparison.  There is an obligation not to introduce new vulnerabilities into existing systems, and the "cost" to long-term compatibility with HTTP is very small: the blacklist becomes a set of simple regexes instead of string literals.

Well, you can either side with ancient de facto behavior and poor
choices made in a standard that is little used today (CGI), or you can
side with a very prevalent standard (HTTP).

Let us suppose that all browsers do implement work-arounds for these
de facto behaviors in CGIs, then we still don't address the other
problems created by this name squashing.

Consider an application that uses a front-end load balancer.  The
application wishes to restrict access to a particular set of external
IP addresses.  Since the load balancer terminates those connections,
the application needs the load balancer to pass on information about
what IP address connected.  This is normal done through
X-Forwarded-For or similar headers, added by the load balancer to the
request.

Of course this introduces a potential vulnerability right off, even
without problematic name squashing.  An attacker could connect from an
untrusted IP address and add his own X-Forwarded-For header.  Ok,
fine, we can address that by configuring the load balancer to strip
the X-Forwarded-For header from the intial request, and then add our
own.

But, if name squashing happens on the application server, then the
load balancer will have to strip "X_Forwarded-For", "X*Forwarded_For",
... ad nauseum.

This is just one specific example of the problem of name squashing.
Modern web frameworks should either reject HTTP header names with
special characters they don't like (nginx apparently does this), or
simply allow through any valid HTTP header names.  No squashing is
needed.

How would this harm web apps that actually rely on HTTP headers?

tim

> [Hill, Brad] I would say the opposite. Given a documented, common practice that, however hacky, has been established for nearly 20 years, there is every reason for a new technology (or at least, relatively new) not to introduce vulnerabilities to a huge and established ecosystem. > > I'm not saying XHR should actually coerce non-alphanumeric characters down when sending headers - only that the security checks for banned headers should do this for purposes of pre-flight comparison. There is an obligation not to introduce new vulnerabilities into existing systems, and the "cost" to long-term compatibility with HTTP is very small: the blacklist becomes a set of simple regexes instead of string literals. Well, you can either side with ancient de facto behavior and poor choices made in a standard that is little used today (CGI), or you can side with a very prevalent standard (HTTP). Let us suppose that all browsers do implement work-arounds for these de facto behaviors in CGIs, then we still don't address the other problems created by this name squashing. Consider an application that uses a front-end load balancer. The application wishes to restrict access to a particular set of external IP addresses. Since the load balancer terminates those connections, the application needs the load balancer to pass on information about what IP address connected. This is normal done through X-Forwarded-For or similar headers, added by the load balancer to the request. Of course this introduces a potential vulnerability right off, even without problematic name squashing. An attacker could connect from an untrusted IP address and add his own X-Forwarded-For header. Ok, fine, we can address that by configuring the load balancer to strip the X-Forwarded-For header from the intial request, and then add our own. But, if name squashing happens on the application server, then the load balancer will have to strip "X_Forwarded-For", "X*Forwarded_For", ... ad nauseum. This is just one specific example of the problem of name squashing. Modern web frameworks should either reject HTTP header names with special characters they don't like (nginx apparently does this), or simply allow through any valid HTTP header names. No squashing is needed. How would this harm web apps that actually rely on HTTP headers? tim