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
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
27 if (!hasFoundInjection) {
28 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking multipart params...");
29 } else {
30 return true;
31 }
32
33 String rawHeader = this.injectionModel.getMediatorUtils().getParameterUtil().getRawHeader();
34 String rawRequest = this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest();
35
36 Matcher matcherBoundary = Pattern.compile("boundary=([^;]*)").matcher(rawHeader);
37
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 (isBoundaryInjectable(rawRequest, boundary, matcherFormDataParameters)) {
50 return true;
51 }
52 }
53
54 return false;
55 }
56
57 private boolean isBoundaryInjectable(String rawRequest, String boundary, Matcher matcherFormDataParameters) {
58
59 String nameParameter = matcherFormDataParameters.group(1);
60 String valueParameter = matcherFormDataParameters.group(2);
61
62 String rawRequestWithStar = rawRequest.replaceAll(
63 "(?i)(Content-Disposition\\s*:\\s*form-data\\s*;\\s*name\\s*=\\s*\"" + nameParameter + "\".*?)([\\\\r\\\\n]*--" + boundary + ")",
64 "$1" + InjectionModel.STAR + "$2"
65 );
66
67 this.injectionModel.getMediatorUtils().getParameterUtil().initializeRequest(rawRequestWithStar);
68
69 try {
70 LOGGER.log(
71 LogLevelUtil.CONSOLE_INFORM,
72 "Checking Multipart boundary injection for {}={}",
73 () -> nameParameter,
74 () -> valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
75 );
76
77 return this.injectionModel.getMediatorMethod().getRequest().testParameters();
78
79 } catch (JSqlException e) {
80 LOGGER.log(
81 LogLevelUtil.CONSOLE_ERROR,
82 String.format(
83 "No Multipart boundary injection for %s=%s",
84 nameParameter,
85 valueParameter.replace(InjectionModel.STAR, StringUtils.EMPTY)
86 )
87 );
88 }
89
90 return false;
91 }
92 }