A Look into Netty’s Recent Security Update (CVE-2015-2156)
May 15, 2015
This post originally appeared on LinkedIn's security site at security.linkedin.com.
As part of our ongoing effort to secure our applications and contribute back to the community, the LinkedIn House Security team is often involved in security testing activities aimed at uncovering vulnerabilities in widely deployed open-source frameworks and applications.
During a recent assessment, we discovered a security flaw within Netty’s cookie parsing code which leads to a universal HttpOnly bypass in Play Framework and potentially other frameworks using Netty as a dependency. The issue has been fixed in Netty 3.9.8.Final, 3.10.3.Final, Netty 4.1.0.Beta5, Netty 4.0.28.Final and Play Framework 2.3.9.
In this blog post, we explain the technical details of the vulnerability and provide information related to the patch issued by the Netty team. A library upgrade is required to fully mitigate the risk.
According to RFC6265, each cookie begins with a name-value pair, followed by zero or more attribute value pairs. In particular, the cookie’s value is defined by the following grammar:
In Netty’s implementation, an improperly terminated cookie value beginning with single-quote or double-quote was not being discarded. Instead, the parsing routine would consume the value till the end of the header or other special characters.
As a result, the value of a cookie could potentially contain the entire Cookie header regardless of cookie’s flags.
The underlying vulnerability in Netty’s code can be easily reproduced with the following code:
aaa=bbb;ccc=ddd as input, the method will correctly return an array with two elements (two cookies).
aaa='bbb;ccc=ddd as input, the bug manifests itself returning a single element in the array.
Impact on Play Framework
At first sight, the bug doesn’t seem to have immediate security implications since the cookies are contained within the same HTTP request. However, under specific circumstances, this bug can be exploited to bypass HttpOnly flag restrictions as illustrated in the following example.￼￼
Play Framework implements CSRF protection using a cookie value (e.g. JSESSIONID) that is compared with a value submitted via HTTP POST parameters (e.g. csrfToken). The cookie is retrieved by server-side components and its value is typically injected as secret token within HTML forms and other elements. During the submission of the HTML form, both values are compared.￼￼
In the presence of the above mentioned vulnerability, a malformed cookie can be used to display the entire cookie header within the resulting HTML page.
In the default configuration of Play framework’s CSRF protection, this vulnerability can be abused to reflect sensitive cookies, even those protected by the HTTPOnly flag within the content of a web page.
From a web attack perspective, this is extremely interesting. In case of Cross-Site Scripting (XSS) attacks or any vulnerability which allows to set arbitrary cookies, this bug can be leveraged to universally bypass the HttpOnly flag in all Play applications. If the HttpOnly flag is included in the HTTP response header, the cookie cannot be accessed through client-side script. In this case, since the cookie’s name-value is entirely included in the DOM, a malicious script can access the content without any restriction.
Many other projects using Netty may be vulnerable to similar "side-effects" of the incorrect cookies parsing routine. We recommend that every project relying on Netty’s CookieDecoder method should mitigate the potential risk by upgrading to the latest version.
As a result of our disclosure, Netty’s cookie parsing code was patched and updated to be strictly RFC6265 compliant. Netty pull request related to this patch can be found at https://github.com/netty/netty/pull/3748.
This vulnerability was discovered by Roman Shafigullin, Luca Carettoni and Mukul Khullar and was reported to Play and Netty teams on 8th April 2015. CVE-2015-2156 has been assigned for this bug.