1 package com.jsql.model.injection.method;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.exception.JSqlException;
5 import com.jsql.model.exception.StoppedByUserSlidingException;
6 import com.jsql.util.I18nUtil;
7 import com.jsql.util.JsonUtil;
8 import com.jsql.util.LogLevelUtil;
9 import org.apache.commons.lang3.StringUtils;
10 import org.apache.logging.log4j.LogManager;
11 import org.apache.logging.log4j.Logger;
12 import org.json.JSONException;
13
14 import java.io.Serializable;
15 import java.util.AbstractMap.SimpleEntry;
16 import java.util.List;
17 import java.util.regex.Pattern;
18
19 public abstract class AbstractMethodInjection implements Serializable {
20
21 private static final Logger LOGGER = LogManager.getRootLogger();
22 public static final String LOG_CHECKING = "LOG_CHECKING";
23
24 protected final InjectionModel injectionModel;
25
26 protected AbstractMethodInjection(InjectionModel injectionModel) {
27 this.injectionModel = injectionModel;
28 }
29
30 public abstract boolean isCheckingAllParam();
31 public abstract String getParamsAsString();
32 public abstract List<SimpleEntry<String, String>> getParams();
33 public abstract String name();
34
35 public boolean testParameters(boolean hasFoundInjection) throws JSqlException {
36 if (!hasFoundInjection) {
37 LOGGER.log(
38 LogLevelUtil.CONSOLE_DEFAULT,
39 "{} [{}] params...",
40 () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING),
41 () -> this.name().toLowerCase()
42 );
43 return this.testParameters();
44 }
45 return true;
46 }
47
48
49
50
51
52
53
54 public boolean testParameters() throws JSqlException {
55 this.injectionModel.setAnalysisReport(StringUtils.EMPTY);
56 var hasFoundInjection = false;
57
58
59
60 if (
61 this != this.injectionModel.getMediatorUtils().connectionUtil().getMethodInjection()
62 && !this.isCheckingAllParam()
63 || this.getParams().isEmpty()
64 ) {
65 return false;
66 }
67
68
69 this.injectionModel.getMediatorUtils().connectionUtil().withMethodInjection(this);
70
71
72 if (
73 this.getParamsAsString().contains(InjectionModel.STAR)
74 || this.injectionModel.getMediatorUtils().connectionUtil().getUrlBase().contains(InjectionModel.STAR)
75 ) {
76 hasFoundInjection = this.checkParamWithStar();
77 } else if (!this.isCheckingAllParam()) {
78 hasFoundInjection = this.checkLastParam();
79 } else {
80 hasFoundInjection = this.checkAllParams();
81 }
82 return hasFoundInjection;
83 }
84
85 private boolean checkParamWithStar() throws JSqlException {
86 SimpleEntry<String, String> parameterToInject = this.getParams().stream()
87 .filter(entry -> entry.getValue().contains("*") || entry.getKey().contains("*"))
88 .findFirst()
89 .orElse(null);
90 if (parameterToInject != null) {
91 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking selected param [{}]...", parameterToInject.getKey());
92 }
93 return this.injectionModel.getMediatorStrategy().testStrategies(parameterToInject);
94 }
95
96
97
98
99 private boolean checkLastParam() throws JSqlException {
100
101
102
103 SimpleEntry<String, String> parameterToInject = this.getParams().stream()
104 .reduce((a, b) -> b)
105 .orElseThrow(() -> new JSqlException("Missing last parameter"));
106 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking default last param [{}]. Use address bar button or preferences to check other params...", parameterToInject.getKey());
107 return this.injectionModel.getMediatorStrategy().testStrategies(parameterToInject);
108 }
109
110
111
112
113
114
115
116 private boolean checkAllParams() throws StoppedByUserSlidingException {
117 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking all params...");
118
119
120 for (SimpleEntry<String, String> paramBase: this.getParams()) {
121
122
123
124 for (SimpleEntry<String, String> paramStar: this.getParams()) {
125 if (paramStar == paramBase) {
126 try {
127 if (this.isParamInjectable(paramStar)) {
128 return true;
129 }
130 } catch (JSONException e) {
131 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
132 }
133 }
134 }
135 }
136 return false;
137 }
138
139 private boolean isParamInjectable(SimpleEntry<String, String> paramStar) throws StoppedByUserSlidingException {
140 boolean hasFoundInjection;
141
142
143 Object jsonEntity = JsonUtil.getJson(paramStar.getValue());
144
145
146 List<SimpleEntry<String, String>> attributesJson = JsonUtil.createEntries(jsonEntity, "root", null);
147
148
149
150
151 if (!attributesJson.isEmpty() && this.injectionModel.getMediatorUtils().preferencesUtil().isCheckingAllJsonParam()) {
152 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "{} [JSON] params...", () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING));
153 hasFoundInjection = this.injectionModel.getMediatorUtils().jsonUtil().testJsonParam(this, paramStar);
154 } else {
155 hasFoundInjection = this.testJsonlessParam(paramStar);
156 }
157 return hasFoundInjection;
158 }
159
160 public boolean testJsonlessParam(SimpleEntry<String, String> paramStar) throws StoppedByUserSlidingException {
161 var hasFoundInjection = false;
162
163 paramStar.setValue(paramStar.getValue() + InjectionModel.STAR);
164
165 try {
166 LOGGER.log(
167 LogLevelUtil.CONSOLE_INFORM,
168 "{} {} param [key:{}, value:{}]",
169 () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING),
170 () -> this.name().toLowerCase(),
171 paramStar::getKey,
172 () -> paramStar.getValue().replace(InjectionModel.STAR, StringUtils.EMPTY)
173 );
174
175
176
177 hasFoundInjection = this.injectionModel.getMediatorStrategy().testStrategies(paramStar);
178
179 } catch (StoppedByUserSlidingException e) {
180 throw e;
181 } catch (JSqlException e) {
182 LOGGER.log(
183 LogLevelUtil.CONSOLE_ERROR,
184 "No {} injection found for parameter {}={} ({})",
185 this.name(),
186 paramStar.getKey(),
187 paramStar.getValue().replaceAll("\\+.?$|\\" + InjectionModel.STAR, StringUtils.EMPTY),
188 e.getMessage()
189 );
190 } finally {
191 if (!hasFoundInjection) {
192
193
194 this.getParams().forEach(e ->
195 e.setValue(
196 e.getValue().replaceAll(Pattern.quote(InjectionModel.STAR) +"$", StringUtils.EMPTY)
197 )
198 );
199
200
201 paramStar.setValue(paramStar.getValue().replace(InjectionModel.STAR, StringUtils.EMPTY));
202 }
203 }
204 return hasFoundInjection;
205 }
206 }