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