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 }