1 package com.jsql.model.injection.strategy;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.accessible.DataAccess;
5 import com.jsql.model.bean.util.Interaction;
6 import com.jsql.model.bean.util.Request;
7 import com.jsql.model.injection.vendor.model.VendorYaml;
8 import com.jsql.model.injection.vendor.model.yaml.Method;
9 import com.jsql.model.suspendable.AbstractSuspendable;
10 import com.jsql.util.I18nUtil;
11 import com.jsql.util.LogLevelUtil;
12 import com.jsql.util.StringUtil;
13 import org.apache.logging.log4j.LogManager;
14 import org.apache.logging.log4j.Logger;
15
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18
19 public class StrategyError extends AbstractStrategy {
20
21 private static final Logger LOGGER = LogManager.getRootLogger();
22
23 private String[] tabCapacityMethod;
24
25 private int indexErrorStrategy = 0;
26
27 public StrategyError(InjectionModel injectionModel) {
28 super(injectionModel);
29 }
30
31 @Override
32 public void checkApplicability() {
33
34 this.isApplicable = false;
35
36 var strategyYaml = this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy();
37
38 if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isStrategyErrorDisabled()) {
39 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, AbstractStrategy.FORMAT_SKIP_STRATEGY_DISABLED, this.getName());
40 return;
41 } else if (strategyYaml.getError().getMethod().isEmpty()) {
42 LOGGER.log(
43 LogLevelUtil.CONSOLE_INFORM,
44 AbstractStrategy.FORMAT_STRATEGY_NOT_IMPLEMENTED,
45 this.getName(),
46 this.injectionModel.getMediatorVendor().getVendor()
47 );
48 return;
49 }
50
51 this.logChecking();
52
53 this.tabCapacityMethod = new String[strategyYaml.getError().getMethod().size()];
54 var indexErrorMethod = 0;
55 var errorCapacity = 0;
56
57 for (Method errorMethod: strategyYaml.getError().getMethod()) {
58 boolean methodIsApplicable = this.isApplicable(errorMethod);
59 if (methodIsApplicable) {
60 Matcher regexSearch = this.getPerformance(errorMethod);
61 if (regexSearch.find()) {
62 errorCapacity = this.getCapacity(indexErrorMethod, errorCapacity, errorMethod, regexSearch);
63 } else {
64 LOGGER.log(
65 LogLevelUtil.CONSOLE_ERROR,
66 "{} {} but injectable size is incorrect",
67 () -> I18nUtil.valueByKey("LOG_VULNERABLE"),
68 errorMethod::getName
69 );
70 methodIsApplicable = false;
71 }
72 }
73
74 if (methodIsApplicable) {
75 this.allow(indexErrorMethod);
76 } else {
77 this.unallow(indexErrorMethod);
78 }
79 indexErrorMethod++;
80 }
81 }
82
83 private boolean isApplicable(Method errorMethod) {
84 var methodIsApplicable = false;
85
86 String performanceSourcePage = this.injectionModel.injectWithoutIndex(
87 this.injectionModel.getMediatorVendor().getVendor().instance().sqlErrorIndice(errorMethod),
88 "error#confirm"
89 );
90
91 var indexZeroToFind = "0";
92 String regexIndexZero = String.format(VendorYaml.FORMAT_INDEX, indexZeroToFind);
93 if (performanceSourcePage.matches("(?s).*"+ regexIndexZero +".*")) {
94 methodIsApplicable = true;
95 this.isApplicable = true;
96 }
97 return methodIsApplicable;
98 }
99
100 private Matcher getPerformance(Method errorMethod) {
101 String performanceErrorSourcePage = this.injectionModel.injectWithoutIndex(
102 this.injectionModel.getMediatorVendor().getVendor().instance().sqlErrorCalibrator(errorMethod),
103 "error#size"
104 );
105 return Pattern.compile("(?s)"+ DataAccess.LEAD +"("+ VendorYaml.CALIBRATOR_SQL +"+)").matcher(performanceErrorSourcePage);
106 }
107
108 private int getCapacity(int indexErrorMethod, int errorCapacityDefault, Method errorMethod, Matcher regexSearch) {
109 int errorCapacityImproved = errorCapacityDefault;
110
111 regexSearch.reset();
112 while (regexSearch.find()) {
113 if (errorCapacityImproved < regexSearch.group(1).length()) {
114 this.indexErrorStrategy = indexErrorMethod;
115 }
116 errorCapacityImproved = regexSearch.group(1).length();
117 this.tabCapacityMethod[indexErrorMethod] = Integer.toString(errorCapacityImproved);
118 }
119
120 int logErrorCapacityImproved = errorCapacityImproved;
121 LOGGER.log(
122 LogLevelUtil.CONSOLE_SUCCESS,
123 "{} [Error {}] showing [{}] characters",
124 () -> I18nUtil.valueByKey("LOG_VULNERABLE"),
125 errorMethod::getName,
126 () -> Integer.toString(logErrorCapacityImproved)
127 );
128
129 return errorCapacityImproved;
130 }
131
132 @Override
133 public void allow(int... indexError) {
134 this.injectionModel.appendAnalysisReport(
135 StringUtil.formatReport(
136 LogLevelUtil.COLOR_BLU,
137 "### Strategy: "+ this.getName() +":"+ this.injectionModel.getMediatorVendor().getVendor().instance()
138 .getModelYaml()
139 .getStrategy()
140 .getError()
141 .getMethod()
142 .get(indexError[0])
143 .getName()
144 )
145 + this.injectionModel.getReportWithoutIndex(
146 this.injectionModel.getMediatorVendor().getVendor().instance().sqlError(
147 StringUtil.formatReport(LogLevelUtil.COLOR_GREEN, "<query>"),
148 "0",
149 indexError[0],
150 true
151 ),
152 "metadataInjectionProcess"
153 )
154 );
155 this.markVulnerability(Interaction.MARK_ERROR_VULNERABLE, indexError[0]);
156 }
157
158 @Override
159 public void unallow(int... indexError) {
160 this.markVulnerability(Interaction.MARK_ERROR_INVULNERABLE, indexError[0]);
161 }
162
163 @Override
164 public String inject(String sqlQuery, String startPosition, AbstractSuspendable stoppable, String metadataInjectionProcess) {
165 return this.injectionModel.injectWithoutIndex(
166 this.injectionModel.getMediatorVendor().getVendor().instance().sqlError(sqlQuery, startPosition, this.indexErrorStrategy, false),
167 metadataInjectionProcess
168 );
169 }
170
171 @Override
172 public void activateWhenApplicable() {
173 if (this.injectionModel.getMediatorStrategy().getStrategy() == null && this.isApplicable()) {
174 LOGGER.log(
175 LogLevelUtil.CONSOLE_INFORM,
176 "{} [{} {}]",
177 () -> I18nUtil.valueByKey("LOG_USING_STRATEGY"),
178 this::getName,
179 () -> this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy()
180 .getError().getMethod().get(this.indexErrorStrategy).getName()
181 );
182 this.injectionModel.getMediatorStrategy().setStrategy(this);
183
184 var request = new Request();
185 request.setMessage(Interaction.MARK_ERROR_STRATEGY);
186 this.injectionModel.sendToViews(request);
187 }
188 }
189
190 @Override
191 public String getPerformanceLength() {
192 return this.tabCapacityMethod[this.indexErrorStrategy];
193 }
194
195 @Override
196 public String getName() {
197 return "Error";
198 }
199
200 public Integer getIndexErrorStrategy() {
201 return this.indexErrorStrategy;
202 }
203
204 public void setIndexErrorStrategy(int indexErrorStrategy) {
205 this.indexErrorStrategy = indexErrorStrategy;
206 }
207 }