We have long had a thesis that when free open-source software projects are forked into commercial versions, then the free open-source version no longer gets the same subsequent level of security updates as the commercial version. Phrased into a question, are the free versions of open-source core products left out in the cold? Earlier this year we were asked by a customer if we could apply our knowledge of open-source security to look at GlassFish Server, a reference implementation for Java EE. Specifically they wanted to know if there were vulnerabilities present in the free GlassFish Open Source Edition that had been patched in the commercial version.
In this post, we disclose vulnerabilities in the open-source version of GlassFish that we discovered using our domain specific language for identifying vulnerabilities, the Security Graph Language (SGL). These issues were all reported to Oracle on 03 May 2017. We worked through a responsible coordinated disclosure process with them and they have published updates protecting users earlier today. Through our disclosure, 4 new Common Vulnerabilities and Exploits (CVEs) for the Oracle GlassFish Server were credited to us.
GlassFish
GlassFish was first released in 2005 by Sun Microsystems. In 2010, Oracle bought Sun Microsystems and committed to a roadmap which included a commercial version called Oracle Glassfish Server. In 2010, commercial support for the Oracle GlassFish Server was discontinued and replaced by the Oracle WebLogic Server. While commercial support was discontinued, security fixes continue to be released in the Oracle Critical Patch Update (CPU) process for users of the commercial product. Aside from the Oracle GlassFish Server, the other version of GlassFish is known as the GlassFish Open Source Edition which is the open-source Java EE Reference Implementation.
Security Graph Language (SGL)
The Security Graph Language (SGL) is the industry’s first Domain Specific Language (DSL) designed to identify security issues in open-source code. With SGL, we put the world’s open-source into a graph database and are then able to traverse the graph of software dependencies for any given project.
To provide an illustration, below is an example of finding the Java libraries which could be vulnerable to External Entity Expansion (XXE) attack(s).
let xml_new = method(class_name: within('javax/xml/parsers/DocumentBuilderFactory',
'javax/xml/stream/XMLInputFactory'),
method_name: within('newInstance', 'newFactory')) in
let xml_set_feature = method(class_name:'javax/xml/parsers/DocumentBuilderFactory',
method_name:'setFeature') in
let xml_set_property = method(class_name:'javax/xml/stream/XMLInputFactory',
method_name:'setProperty') in
let results = xml_new called_by
not(union(calls xml_set_feature, xml_set_property)) in results
# Example of a XXE pattern formed to find similar XXE bugs
SGL empowers us with super-powers to express a security pattern and enumerate the entire graph of libraries with ease.
Issues discovered in open-source GlassFish Server
We found a total of 23 issues in the open-source GlassFish server. Of those 23 issues, 10 fixed by Oracle, while 13 were not fixed as the GlassFish versions affected are no longer being maintained.
Out of the 10 issues that were fixed issues, 7 had no previous CVE, and all of them affected the latest version of the GlassFish Open Source Edition at the time of discovery.
Disclosure Timeline
4 April 2017 - Discovered 21 direct issues in GlassFish
3 May 2017 - Contacted maintainer
4 May 2017 - Maintainer responded
4 May 2017 - Provided Information to the maintainer
6 May 2017 - Tracking number received
2 June 2017 - Contacted maintainer to follow up with our 30-day disclosure policy
7 June 2017 - Maintainer requested an extension
22 June 2017 - Maintainer seek clarification on some issues
22 June 2017 - Provided clarification to maintainer
28 June 2017 - Provided more information to maintainer
13 July 2017 - Seek for updates from maintainer
14 July 2017 - Maintainer requested an extension
26 August 2017 - Maintainer provided granular tracking numbers for individual issue
8 September 2017 - Maintainer published GlassFish Open Source Edition 5.0
27 September 2017 - Seek for updates from maintainer
28 September 2017 - Maintainer asked for an extension till 17 October 2017
17 October 2017 - Maintainer releases October CPU 2017
17 October 2017 - Published details on the issues
The remainder of this post will contain information on all 23 disclosed direct issues.
Summary of Issues
The table below provides an overview of the 10 issues that were fixed through our disclosure.
CVE / NON CVE |
Issue Summary | 3.x (Maven) |
3.0.1.x (Oracle) |
3.1.2.x (Oracle) |
4.0.x, 4.1.x (Maven) |
5.0 (Maven) |
---|---|---|---|---|---|---|
Non CVE 1 | Information Disclosure via MessageFormat parameters | N.A. | N.A. | N.A. | ✖ | ✓ |
Non CVE 2 | Cross-Site Scripting (XSS) via configNameSection | ✖ | N.A. | ✓ | ✖ | ✓ |
Non CVE 3 | Deserialization flaw | ✖ | ✓ | ✓ | ✖ | ✓ |
Non CVE 4 | Denial of Service (DoS) via file upload requests | ✖ | N.A. | N.A. | ✖ | ✓ |
Non CVE 5 | Handle Proxy Header (HTTPoxy) in CGISERVLET | ✖ | ✓ | ✓ | ✖ | ✓ |
Non CVE 6 | Deprecated SSLv3 enabled by default | ✖ | N.A. | N.A. | ✖ | ✓ |
Non CVE 7 | Security Manager Bypass | ✖ | ✓ | ✓ | ✖ | ✓ |
CVE-2016-3607 | Remote Code Execution (RCE) via NULL byte injection | ✖ | N.A. | N.A. | ✖ | ✓ |
CVE-2016-3608 | Directory Traversal via unicode encoding payload | ✖ | N.A. | N.A. | ✖ | ✓ |
CVE-2016-5477 | Directory Traversal via unicode encoding payload | ✖ | N.A. | N.A. | ✖ | ✓ |
The remaining 13 issues were not fixed in the Open Source Edition as it affects versions which are no longer maintained.
CVE / NON CVE |
Issue Summary | 3.0.x (Maven) |
3.1.x (Maven) |
3.2.x (Maven) |
---|---|---|---|---|
Non CVE 8, Not fixed |
Information Disclosure via error message | N.A. | ✖ | ✖ |
Non CVE 9, Not fixed |
Information Disclosure via server.log | N.A. | ✖ | ✖ |
CVE-2011-0807 | Remote Code Execution (RCE) via default admin account | ✖ | ✖ | ✖ |
CVE-2011-1511 | Information Disclosure via TRACE requests | ✖ | ✖ | N.A. |
CVE-2011-3559 | Denial of Service (DoS) via range header | ✖ | ✖ | ✖ |
CVE-2011-5035 | Denial of Service (DoS) via hash table collisions | ✖ | ✖ | ✖ |
CVE-2012-0081 | Unauthorized creation of Domain via admin-cli | ✖ | ✖ | N.A. |
CVE-2012-0104 | Denial of Service (DoS) via conversion of named encoding into Charsets | ✖ | ✖ | ✖ |
CVE-2012-0550 | Cross-Site Request Forgery (CSRF) via REST component | ✖ | ✖ | ✖ |
CVE-2012-0551 | Cross-Site Scripting (XSS) via administrator console | ✖ | ✖ | ✖ |
CVE-2012-3155 | Denial of Service (DoS) via administrator console | ✖ | ✖ | ✖ |
CVE-2013-1508 | Cross-Site Scripting (XSS) via REST component | ✖ | ✖ | ✖ |
CVE-2013-1515 | Cross-Site Scripting (XSS) via administration console | ✖ | ✖ | ✖ |
Credited Common Vulnerabilities and Exploits (CVEs)
From the list of issues above, the following 4 CVEs were credited to us by the maintainers on the commercial version of Oracle GlassFish Server, and these were included in today's release of the Oracle CPU October 2017.
CVE | Issue Summary |
---|---|
Non CVE 7, CVE-2017-10385 |
Security Manager Bypass |
Non CVE 3, CVE-2017-10391 |
Deserialization flaw |
Non CVE 5, CVE-2017-10393 |
Handle Proxy Header (HTTPoxy) in CGISERVLET |
Non CVE 2, CVE-2017-10400 |
Cross-Site Scripting (XSS) via configNameSection |
How we discovered these issues
We took several approaches to discover these issues.
One of our approaches was to collect several known bugs, from other application servers, and test if GlassFish contained similar bugs. As an example used SGL to enumerate a known XXE pattern over the entire call graph of the project.
Security Manager bypass
The issue of Security Manager bypass is not new, and the requirements to introduce this weakness is loose. This issue was also present in a similar application server, the Apache Tomcat. To reconstruct an existing issue like in CVE-2016-0763, we can construct an SGL query which contains the vulnerable pattern like the following:
sgl> let set_global_context = method(class_name:'org/apache/naming/factory/ResourceLinkFactory', method_name:'setGlobalContext') in
let get_security_manager = method(class_name:'java/lang/System', method_name:'getSecurityManager') in
let check_permission = method(class_name:'java/lang/SecurityManager', method_name:'checkPermission') in
set_global_context called_by not(union(calls get_security_manager, calls check_permission))
method(module_name:'null', class_name:'org/apache/catalina/core/NamingContextListener', method_name:'lifecycleEvent', descriptor:'(Lorg/apache/catalina/LifecycleEvent;)')
The query above would display all methods that calls the setGlobalContext method, and not make a call to both the getSecurityManager and checkPermission methods.
To take it a step further, we can now use the identified method to display all affected libraries by adding a single traversal step, method_in_library.
sgl> set_global_context called_by not(union(calls get_security_manager, calls check_permission)) method_in_library
…
library(language:'java', coord1:'org.glassfish.main.web', coord2:'web-core', version:'4.1.1')
library(language:'java', coord1:'org.glassfish.main.web', coord2:'web-core', version:'4.0-b72')
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1')
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1.1')
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1.2')
…
The results above were subsequently verified and we catalogued the vulnerability as "Non CVE 7" in the table of listing above.
Improper Handling of File
Before Java 7 Update 40, file manipulation during Java Object Deserializable happens when handling a File object which contained a NULL byte. The following SGL query would allow us to instances of readObject defined in GlassFish, and makes a call to java/io/File's getPath method.
sgl> let glassfish_class = class(regex 'org.glassfish.*') in
let read_object = method(method_name:'readObject') in
let get_path = method(class_name:'java/io/File', method_name:'getPath') in
glassfish_class defines read_object where(calls get_path)
From the result set, we could narrow the results further by adding more known pattern of codes that would introduce a weakness to the project. We found that we could also reach glassfish_class by traversing the graph in the reverse direction.
get_path called_by read_object where(defined_by glassfish_class)
This was useful by reducing the number of traversals, and allowed us to reach the callers of a method, instead of tracing the calls. It is useful to perform static analysis of callers where a vulnerable method is already known, demonstrated by the following example.
The results from the above query was then catalogued as "CVE-2016-3607" as it was found to closely match an existing CVE for the commercial Oracle GlassFish Server.
Usage of SSLv3
SSLv3 has been deprecated by the IETF. In GlassFish, there is a method setSsl3Enabled which is set by default to true and as you can see SGL returns the versions affected.
sgl> let set_ssl3_enabled = method(method_name:'setSsl3Enabled') in
set_ssl3_enabled called_by method_in_library
...
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1')
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1.1')
library(language:'java', coord1:'org.glassfish.main.extras', coord2:'glassfish-embedded-all', version:'4.1.2')
library(language:'java', coord1:'org.glassfish.main.security', coord2:'security', version:'4.1')
library(language:'java', coord1:'org.glassfish.main.security', coord2:'security', version:'4.1.1')
library(language:'java', coord1:'org.glassfish.security', coord2:'security', version:'3.1.1-b09')
library(language:'java', coord1:'org.glassfish.security', coord2:'security', version:'3.1.1-b10')
library(language:'java', coord1:'org.glassfish.main.security', coord2:'security', version:'3.1.2')
library(language:'java', coord1:'org.glassfish.main.security', coord2:'security', version:'3.1.2.2')
library(language:'java', coord1:'org.glassfish.common', coord2:'glassfish-mbeanserver', version:'3.1')
library(language:'java', coord1:'org.glassfish.common', coord2:'glassfish-mbeanserver', version:'3.1.1')
library(language:'java', coord1:'org.glassfish.common', coord2:'glassfish-mbeanserver', version:'3.1-b26')
library(language:'java', coord1:'org.glassfish.common', coord2:'glassfish-mbeanserver', version:'3.1-b27')
...
After we have reviewed the results and confirming that the weakness exists, we have catalogued this vulnerability as "Non CVE 6".
Denial of Service (DoS) via File Upload Requests
We then took an existing vulnerability in Apache Commons Fileupload library, CVE-2016-3092, and tried to detect all instances which contained this issue where the method did not throw an IllegalArgumentException.
sgl> let multipartstream_init = method(class_name:'org/apache/catalina/fileupload/MultipartStream', method_name:'<init>', descriptor:'(Ljava/io/InputStream;[BILorg/apache/catalina/fileupload/MultipartStream$ProgressNotifier;)') in
let illegal_argument_exception = method(class_name:'java/lang/IllegalArgumentException', method_name:'<init>', descriptor:'(Ljava/lang/String;)' in
multipartstream_init not(calls illegal_argument_exception)
With the above SGL query, we found multiple leads which led us to believe that GlassFish Open Source was similarly affected. With a little further investigation, we concluded that GlassFish Open Source was vulnerable to a Denial of Service (DoS) weakness and have catalogued this vulnerability as "Non CVE 4".
Continuous Security with the Security Graph Language
By expressing software issues into SGL queries, and continuously building up the amount of SGL queries, the Security Graph Language is an integral part of continuous security by automatically identifying issues as new software gets published.
Similarly, as new SGL queries gets expressed, the query would be ran over the entire world of open-source to collect a result set of issues. The funneled result set obtained by the SGL queries narrows the space of software to allow Security Researchers to efficiently confirm, publish, and produce new security advisories and patches.
Summary
Users of the GlassFish Open Source Edition should update to version 5.0 as soon as possible. Oracle will not be releasing patches for version 3, and will only be releasing fixes for version 4 at a later date.
SGL, together with our knowledgebase of vulnerabilities is proving very powerful to discover new issues in open-source projects.