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
SM
Steven M. Christey
Fri, Jan 6, 2012 6:14 PM

On Fri, 6 Jan 2012, Hill, Brad wrote:

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.

(disclaimer: I'm late to this discussion and haven't seen all the posts.)

The industry does this all the time, for example by accounting for
non-standard browser behavior with XSS defenses (as reflected in the XSS
cheat sheet, HTML5 Security Cheatsheet, etc).  Not that this has been
wildly successful given all the XSS variants that keep cropping up that
only apply to 1 or 2 browsers, but it seems like a reasonable approach
short of normalizing inputs/outputs in a predictable fashion
(non-standard), or modifying the standards to design out these kinds of
problems in the first place (unrealistic, infeasible, and maybe
impossible).  Anti-virus products, IDS, mail scanners, and other products
also have to wrestle with the same issue of accounting for
popular-but-non-standard behaviors in order to work properly.  Should they
be responsible for this kind of protection?  Philosophically speaking, no;
but operationally speaking, they have no choice.

  • Steve

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


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

On Fri, 6 Jan 2012, Hill, Brad wrote: > 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. (disclaimer: I'm late to this discussion and haven't seen all the posts.) The industry does this all the time, for example by accounting for non-standard browser behavior with XSS defenses (as reflected in the XSS cheat sheet, HTML5 Security Cheatsheet, etc). Not that this has been wildly successful given all the XSS variants that keep cropping up that only apply to 1 or 2 browsers, but it seems like a reasonable approach short of normalizing inputs/outputs in a predictable fashion (non-standard), or modifying the standards to design out these kinds of problems in the first place (unrealistic, infeasible, and maybe impossible). Anti-virus products, IDS, mail scanners, and other products also have to wrestle with the same issue of accounting for popular-but-non-standard behaviors in order to work properly. Should they be responsible for this kind of protection? Philosophically speaking, no; but operationally speaking, they have no choice. - Steve > 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 > > > _______________________________________________ > 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 >
T
Tim
Fri, Jan 6, 2012 6:34 PM

Hi Steve,

(disclaimer: I'm late to this discussion and haven't seen all the posts.)

The industry does this all the time, for example by accounting for
non-standard browser behavior with XSS defenses (as reflected in the
XSS cheat sheet, HTML5 Security Cheatsheet, etc).  Not that this has
been wildly successful given all the XSS variants that keep cropping
up that only apply to 1 or 2 browsers, but it seems like a
reasonable approach short of normalizing inputs/outputs in a
predictable fashion (non-standard), or modifying the standards to
design out these kinds of problems in the first place (unrealistic,
infeasible, and maybe impossible).  Anti-virus products, IDS, mail
scanners, and other products also have to wrestle with the same
issue of accounting for popular-but-non-standard behaviors in order
to work properly.  Should they be responsible for this kind of
protection?  Philosophically speaking, no; but operationally
speaking, they have no choice.

I appreciate what you're saying, and yes, many de facto hacks exist to
protect people.  The more I think about it, the more I think that
nearly all web frameworks probably do this header namespace squashing.
The squashing clearly creates security problems, as we have discussed.

Let us balance that then against the security down sides of making a
change to web frameworks.  If today, "X^MyHeader" and "X*MyHeader" are
treated as equivalent, what is the harm in not treating them as
equivalent in the future?  The only header an application can search
for is "X_MYHEADER".  If we make such a change, they're still going to
be looking up "X_MYHEADER".  Sure, applications sending that header
would need to be more careful about what format of the header they are
sending (such as sending "X_MyHeader" in all cases) , but that's not a
security issue, just a backward compatibility one.  How would the
application be harmed in a security sense?

Brad's suggested approach would be to start restricting the types of
headers that can be sent to begin with.  So if XMLHttpRequest simply
blocked the less common variants of these headers (essentially
rejecting "Accept[!#$%&'*+-._^`|~]Encoding", and so on), then great,
we've prevented these headers from working their way in to these
requests at the web layer.  But as I've pointed out, there are other
situations where this approach would need to be taken.  Essentially,
to enforce it, all servers would need to start rejecting the uncommon
characters.  This amounts to changing the HTTP spec.  From a security
perspective, this clearly prevents a lot of problems, but changing
HTTP header names from a permissive set of characters to a restrictive
set is difficult.  Any legacy servers will continue to be "vulnerable"
in a sense, basically forever.

Both changes are very difficult from an implementation perspective,
but if there are no security downsides to fixing web frameworks
(allowing most/all HTTP headers), then that seems like the better
approach to me, not to mention easier.

tim

Hi Steve, > (disclaimer: I'm late to this discussion and haven't seen all the posts.) > > The industry does this all the time, for example by accounting for > non-standard browser behavior with XSS defenses (as reflected in the > XSS cheat sheet, HTML5 Security Cheatsheet, etc). Not that this has > been wildly successful given all the XSS variants that keep cropping > up that only apply to 1 or 2 browsers, but it seems like a > reasonable approach short of normalizing inputs/outputs in a > predictable fashion (non-standard), or modifying the standards to > design out these kinds of problems in the first place (unrealistic, > infeasible, and maybe impossible). Anti-virus products, IDS, mail > scanners, and other products also have to wrestle with the same > issue of accounting for popular-but-non-standard behaviors in order > to work properly. Should they be responsible for this kind of > protection? Philosophically speaking, no; but operationally > speaking, they have no choice. I appreciate what you're saying, and yes, many de facto hacks exist to protect people. The more I think about it, the more I think that nearly all web frameworks probably do this header namespace squashing. The squashing clearly creates security problems, as we have discussed. Let us balance that then against the security down sides of making a change to web frameworks. If today, "X^MyHeader" and "X*MyHeader" are treated as equivalent, what is the harm in not treating them as equivalent in the future? The only header an application can search for is "X_MYHEADER". If we make such a change, they're still going to be looking up "X_MYHEADER". Sure, applications sending that header would need to be more careful about what format of the header they are sending (such as sending "X_MyHeader" in all cases) , but that's not a security issue, just a backward compatibility one. How would the application be harmed in a security sense? Brad's suggested approach would be to start restricting the types of headers that can be sent to begin with. So if XMLHttpRequest simply blocked the less common variants of these headers (essentially rejecting "Accept[!#$%&'*+-._^`|~]Encoding", and so on), then great, we've prevented these headers from working their way in to these requests at the web layer. But as I've pointed out, there are other situations where this approach would need to be taken. Essentially, to enforce it, all servers would need to start rejecting the uncommon characters. This amounts to changing the HTTP spec. From a security perspective, this clearly prevents a lot of problems, but changing HTTP header names from a permissive set of characters to a restrictive set is difficult. Any legacy servers will continue to be "vulnerable" in a sense, basically forever. Both changes are very difficult from an implementation perspective, but if there are no security downsides to fixing web frameworks (allowing most/all HTTP headers), then that seems like the better approach to me, not to mention easier. tim
HB
Hill, Brad
Fri, Jan 6, 2012 7:31 PM

Looks like this is a quite old issue, dating to 2007 with Flash:

http://kuza55.blogspot.com/2007/07/exploiting-reflected-xss.html

Adobe patched, it but the W3C editors for XHR won't:

http://lists.w3.org/Archives/Public/public-webapps/2012JanMar/0024.html

-----Original Message-----
From: websecurity-bounces@lists.webappsec.org [mailto:websecurity-
bounces@lists.webappsec.org] On Behalf Of Hill, Brad
Sent: Friday, January 06, 2012 9:19 AM
To: Tim
Cc: websecurity@lists.webappsec.org
Subject: Re: [WEB SECURITY] A technique for bypassing request header
restriction of XMLHttpRequest

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


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

Looks like this is a quite old issue, dating to 2007 with Flash: http://kuza55.blogspot.com/2007/07/exploiting-reflected-xss.html Adobe patched, it but the W3C editors for XHR won't: http://lists.w3.org/Archives/Public/public-webapps/2012JanMar/0024.html > -----Original Message----- > From: websecurity-bounces@lists.webappsec.org [mailto:websecurity- > bounces@lists.webappsec.org] On Behalf Of Hill, Brad > Sent: Friday, January 06, 2012 9:19 AM > To: Tim > Cc: websecurity@lists.webappsec.org > Subject: Re: [WEB SECURITY] A technique for bypassing request header > restriction of XMLHttpRequest > > > 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 > > > _______________________________________________ > 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
SE
super evr
Mon, Jan 9, 2012 7:46 PM

In my testing, Apache did not handle all "bypassed" headers the same
way. For example, it was not possible to submit a modified
"Transfer-Encoding" header (eg. Transfer.Encoding; Transfer*Encoding;
Transfer Encoding), and have Apache handle the request with the
specified encoding.

The environment variable HTTP_TRANSFER_ENCODING is still set, but the
actual request isn't treated with the provided encoding.

If you could get the browser to send a Transfer*Encoding Header, and
if Apache treats it like normal, then you could possibly abuse it for
Request Splitting/Smuggling.
http://www.mindedsecurity.com/MSA01240108.html

On Thu, Jan 5, 2012 at 4: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

In my testing, Apache did not handle all "bypassed" headers the same way. For example, it was not possible to submit a modified "Transfer-Encoding" header (eg. Transfer.Encoding; Transfer*Encoding; Transfer Encoding), and have Apache handle the request with the specified encoding. The environment variable HTTP_TRANSFER_ENCODING is still set, but the actual request isn't treated with the provided encoding. If you could get the browser to send a Transfer*Encoding Header, and if Apache treats it like normal, then you could possibly abuse it for Request Splitting/Smuggling. http://www.mindedsecurity.com/MSA01240108.html On Thu, Jan 5, 2012 at 4: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, Feb 2, 2012 1:19 AM

Ack.  I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs.  :(

-----Original Message-----
From: websecurity-bounces@lists.webappsec.org [mailto:websecurity-
bounces@lists.webappsec.org] On Behalf Of Hill, Brad
Sent: Friday, January 06, 2012 9:19 AM
To: Tim
Cc: websecurity@lists.webappsec.org
Subject: Re: [WEB SECURITY] A technique for bypassing request header
restriction of XMLHttpRequest

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


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

Ack. I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs. :( > -----Original Message----- > From: websecurity-bounces@lists.webappsec.org [mailto:websecurity- > bounces@lists.webappsec.org] On Behalf Of Hill, Brad > Sent: Friday, January 06, 2012 9:19 AM > To: Tim > Cc: websecurity@lists.webappsec.org > Subject: Re: [WEB SECURITY] A technique for bypassing request header > restriction of XMLHttpRequest > > > 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 > > > _______________________________________________ > 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
T
Tim
Thu, Feb 2, 2012 8:22 PM

Ack.  I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs.  :(

Yeah, after our conversation a while back, I looked into a bit more
and realized that just about every web framework does this foolish
transliteration of characters to _.  Almost every special character is
converted like this.  The CGI spec only requires - be transliterated
to _ and doesn't require anything else be.

Of course those other frameworks don't have to adhere to CGI, but even
if their developers wanted to claim "oh, we're just being backward
compatible with CGI", they don't have a sound argument.

tim

> Ack. I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs. :( Yeah, after our conversation a while back, I looked into a bit more and realized that just about every web framework does this foolish transliteration of characters to _. Almost every special character is converted like this. The CGI spec only requires - be transliterated to _ and doesn't require anything else be. Of course those other frameworks don't have to adhere to CGI, but even if their developers wanted to claim "oh, we're just being backward compatible with CGI", they don't have a sound argument. tim
RA
Robert A.
Thu, Feb 2, 2012 8:27 PM

In your investigation did you find an instance of a framework converting single header names
such as _Referer or _Host?

Regards,

  • Robert

On Thu, 2 Feb 2012, Tim wrote:

Ack.  I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs.  :(

Yeah, after our conversation a while back, I looked into a bit more
and realized that just about every web framework does this foolish
transliteration of characters to _.  Almost every special character is
converted like this.  The CGI spec only requires - be transliterated
to _ and doesn't require anything else be.

Of course those other frameworks don't have to adhere to CGI, but even
if their developers wanted to claim "oh, we're just being backward
compatible with CGI", they don't have a sound argument.

tim


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

In your investigation did you find an instance of a framework converting single header names such as _Referer or _Host? Regards, - Robert On Thu, 2 Feb 2012, Tim wrote: > >> Ack. I am learning PHP today to write some test cases and I find that PHP also uses the "-" to "_" conversion before exposing HTTP headers, so this server vulnerability is much more widespread than just ancient CGIs. :( > > Yeah, after our conversation a while back, I looked into a bit more > and realized that just about every web framework does this foolish > transliteration of characters to _. Almost every special character is > converted like this. The CGI spec only requires - be transliterated > to _ and doesn't require anything else be. > > Of course those other frameworks don't have to adhere to CGI, but even > if their developers wanted to claim "oh, we're just being backward > compatible with CGI", they don't have a sound argument. > > tim > > _______________________________________________ > 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 >