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      private static final Logger LOGGER = LogManager.getRootLogger();
15  
16      private final InjectionModel injectionModel;
17  
18      public MultipartUtil(InjectionModel injectionModel) {
19          this.injectionModel = injectionModel;
20      }
21  
22      public boolean testParameters(boolean hasFoundInjection) {
23          if (!hasFoundInjection) {
24              LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "{} multipart...", () -> I18nUtil.valueByKey("LOG_CHECKING"));
25          } else {
26              return true;
27          }
28          
29          String rawHeader = this.injectionModel.getMediatorUtils().getParameterUtil().getRawHeader();
30          String rawRequest = this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest();
31  
32          Matcher matcherBoundary = Pattern.compile("boundary=([^;]*)").matcher(rawHeader);
33          if (!matcherBoundary.find()) {
34              return false;
35          }
36          
37          String boundary = matcherBoundary.group(1);
38  
39          Matcher matcherFormDataParameters = Pattern
40              .compile("Content-Disposition\\s*:\\s*form-data\\s*;\\s*name\\s*=\"(.*?)\"(.*?)--" + boundary, Pattern.DOTALL)
41              .matcher(rawRequest);
42  
43          while (matcherFormDataParameters.find()) {
44              if (this.isBoundaryInjectable(rawRequest, boundary, matcherFormDataParameters)) {
45                  return true;
46              }
47          }
48          return false;
49      }
50  
51      private boolean isBoundaryInjectable(String rawRequest, String boundary, Matcher matcherFormDataParameters) {
52          String nameParameter = matcherFormDataParameters.group(1);
53          String valueParameter = matcherFormDataParameters.group(2);
54  
55          String rawRequestWithStar = rawRequest.replaceAll(
56              "(?i)(Content-Disposition\\s*:\\s*form-data\\s*;\\s*name\\s*=\\s*\"" + nameParameter + "\".*?)([\\\\r\\\\n]*--" + boundary + ")",
57              "$1" + InjectionModel.STAR + "$2"
58          );
59  
60          this.injectionModel.getMediatorUtils().getParameterUtil().initRequest(rawRequestWithStar);
61  
62          try {
63              LOGGER.log(
64                  LogLevelUtil.CONSOLE_INFORM,
65                  "{} multipart boundary {}={}",
66                  () -> I18nUtil.valueByKey("LOG_CHECKING"),
67                  () -> nameParameter,
68                  () -> valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
69              );
70              return this.injectionModel.getMediatorMethod().getRequest().testParameters();
71          } catch (JSqlException e) {
72              LOGGER.log(
73                  LogLevelUtil.CONSOLE_ERROR,
74                  String.format(
75                      "No Multipart boundary injection for %s=%s",
76                      nameParameter,
77                      valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
78                  )
79              );
80          }
81          return false;
82      }
83  }