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