A curious bug

I spent some time yesterday debugging a very curious bug. 

One of the apps that my team maintains is a lightweight HTTP proxy written in Java. It acts as a Route Service for apps running in Cloud Foundry.

Today, a user reported that Cross-Origin Request (CORS) functionality in their application stopped working once they inserted this proxy into their request flow. Their analysis showed that the 'Origin' header, which is critical to the CORS flow, wasn't reaching their application. Our proxy was filtering out this 'Origin' header.

This report led to a very interesting debugging session which revealed a rather surprising root cause. Our application uses `HttpURLConnection`, which is the built-in Java class for making HTTP connections. It turns out that this class keeps a list of `restrictedHeaders` that it does not allow client code to specify. Here's the list: 

String[] restrictedHeaders = {
	/* Restricted by XMLHttpRequest2 */
	//"Accept-Charset",
	//"Accept-Encoding",
	"Access-Control-Request-Headers",
	"Access-Control-Request-Method",
	"Connection", /* close is allowed */
	"Content-Length",
	//"Cookie",
	//"Cookie2",
	"Content-Transfer-Encoding",
	//"Date",
	//"Expect",
	"Host",
	"Keep-Alive",
	"Origin",
	// "Referer",
	// "TE",
	"Trailer",
	"Transfer-Encoding",
	"Upgrade",
	//"User-Agent",
	"Via"
};

If the calling code does set a value for one of these headers, it is either ignored or stripped, depending on the header.

Do you notice anything interesting about this list of headers? That first comment -- Restricted by XMLHttpRequest2 -- gives it away. This is the same list of headers that a web browser restricts application code from specifying!

From https://fetch.spec.whatwg.org/#forbidden-header-name

A forbidden header name is a header name that is a byte-case-insensitive 
match for one of:

	`Accept-Charset`
	`Accept-Encoding`
	`Access-Control-Request-Headers`
	`Access-Control-Request-Method`
	`Connection`
	`Content-Length`
	`Cookie`
	`Cookie2`
	`Date`
	`DNT`
	`Expect`
	`Host`
	`Keep-Alive`
	`Origin`
	`Referer`
	`TE`
	`Trailer`
	`Transfer-Encoding`
	`Upgrade`
	`Via`

So why is this Java class enforcing restrictions that originated in the web browser world?

Applets

You may remember that not too long ago, Java applets were a big thing. They were the dominant mechanism for delivering rich content inside web browsers, before Flash came along.

So since applets were essentially Java code running inside a web browser, they faced similar security challenges as regular web pages. So it made sense to adopt some of the same security solutions as the browsers did - including restricting the headers that application code can specify!

Was my reasoning correct? Was this change specifically related to applets?

The JDK commit message that introduced this change in 2010 doesn't reveal much:

6980004: limit HTTP request cookie headers in HttpURLConnection

I could find two CVEs that obliquely reference this issue. Here's the description of CVE-2010-3573:

Unspecified vulnerability in the Networking component in Oracle Java SE ... allows remote attackers to affect confidentiality, integrity, and availability via unknown vectors. ... this is related to missing validation of request headers in the HttpURLConnection class when they are set by applets, which allows remote attackers to bypass the intended security policy.

So there's definitely a connection and this restriction makes sense in the applet execution context.

What is unclear to me is why didn't they enforce this restriction only in an applet context. Why was this made the default?

要查看或添加评论,请登录

Deepak Sarda的更多文章

  • The Paradox of Choice

    The Paradox of Choice

    I read an insightful article today addressing the paradox of choice many people encounter when starting to invest. I…

  • Don’t ignore Chaos testing!

    Don’t ignore Chaos testing!

    In my previous role, I led the product development & delivery of observability services. This included passive…

    2 条评论
  • A rookie mistake

    A rookie mistake

    Consider the following function : Can you spot the error in this function? It makes the rookie mistake of assuming that…

    1 条评论

社区洞察

其他会员也浏览了