View Javadoc
1   package com.jsql.util;
2   
3   import com.jsql.model.InjectionModel;
4   import com.jsql.model.exception.JSqlException;
5   import com.jsql.model.injection.method.AbstractMethodInjection;
6   import org.apache.commons.lang3.StringUtils;
7   import org.apache.logging.log4j.LogManager;
8   import org.apache.logging.log4j.Logger;
9   
10  import java.util.regex.Matcher;
11  import java.util.regex.Pattern;
12  
13  public class MultipartUtil {
14  
15      private static final Logger LOGGER = LogManager.getRootLogger();
16  
17      private final InjectionModel injectionModel;
18  
19      public MultipartUtil(InjectionModel injectionModel) {
20          this.injectionModel = injectionModel;
21      }
22  
23      public boolean testParameters(boolean hasFoundInjection) {
24          if (!hasFoundInjection) {
25              LOGGER.log(
26                  LogLevelUtil.CONSOLE_DEFAULT,
27                  "{} [multipart] params...",
28                  () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING)
29              );
30          } else {
31              return true;
32          }
33          
34          String rawHeader = this.injectionModel.getMediatorUtils().parameterUtil().getRawHeader();
35          String rawRequest = this.injectionModel.getMediatorUtils().parameterUtil().getRawRequest();
36  
37          Matcher matcherBoundary = Pattern.compile("boundary=([^;]*)").matcher(rawHeader);
38          if (!matcherBoundary.find()) {
39              return false;
40          }
41          
42          String boundary = matcherBoundary.group(1);
43  
44          Matcher matcherFormDataParameters = Pattern
45              .compile("Content-Disposition\\s*:\\s*form-data\\s*;\\s*name\\s*=\"(.*?)\"(.*?)--" + boundary, Pattern.DOTALL)
46              .matcher(rawRequest);
47  
48          while (matcherFormDataParameters.find()) {
49              if (this.isBoundaryInjectable(rawRequest, boundary, matcherFormDataParameters)) {
50                  return true;
51              }
52          }
53          return false;
54      }
55  
56      private boolean isBoundaryInjectable(String rawRequest, String boundary, Matcher matcherFormDataParameters) {
57          String nameParameter = matcherFormDataParameters.group(1);
58          String valueParameter = matcherFormDataParameters.group(2);
59  
60          String rawRequestWithStar = rawRequest.replaceAll(
61              "(?i)(Content-Disposition\\s*:\\s*form-data\\s*;\\s*name\\s*=\\s*\"" + nameParameter + "\".*?)([\\\\r\\\\n]*--" + boundary + ")",
62              "$1" + InjectionModel.STAR + "$2"
63          );
64  
65          this.injectionModel.getMediatorUtils().parameterUtil().initRequest(rawRequestWithStar);
66  
67          try {
68              LOGGER.log(
69                  LogLevelUtil.CONSOLE_INFORM,
70                  "{} multipart boundary {}={}",
71                  () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING),
72                  () -> nameParameter,
73                  () -> valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
74              );
75              return this.injectionModel.getMediatorMethod().getRequest().testParameters();
76          } catch (JSqlException e) {
77              LOGGER.log(
78                  LogLevelUtil.CONSOLE_ERROR,
79                  String.format(
80                      "No Multipart boundary injection for %s=%s",
81                      nameParameter,
82                      valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
83                  )
84              );
85          }
86          return false;
87      }
88  }