View Javadoc
1   package com.jsql.util;
2   
3   import com.jsql.model.InjectionModel;
4   import org.apache.logging.log4j.LogManager;
5   import org.apache.logging.log4j.Logger;
6   import org.jsoup.Jsoup;
7   import org.jsoup.nodes.Element;
8   import org.jsoup.select.Elements;
9   
10  import java.util.AbstractMap.SimpleEntry;
11  import java.util.*;
12  import java.util.Map.Entry;
13  
14  public class FormUtil {
15      
16      /**
17       * Log4j logger sent to view.
18       */
19      private static final Logger LOGGER = LogManager.getRootLogger();
20      
21      private static final String INPUT_ATTR_VALUE = "value";
22      private static final String FORM_ATTR_VALUE = "method";
23      
24      private final InjectionModel injectionModel;
25      
26      public FormUtil(InjectionModel injectionModel) {
27          this.injectionModel = injectionModel;
28      }
29  
30      public void parseForms(int statusCode, String pageSource) {
31          
32          var elementsForm = Jsoup.parse(pageSource).select("form");
33          
34          if (elementsForm.isEmpty()) {
35              return;
36          }
37          
38          var result = new StringBuilder();
39          
40          Map<Element, List<Element>> mapForms = new HashMap<>();
41          
42          for (Element form: elementsForm) {
43              
44              mapForms.put(form, new ArrayList<>());
45              
46              result.append(
47                  String.format(
48                      "%n<form action=\"%s\" method=\"%s\" />",
49                      form.attr("action"),
50                      form.attr(FORM_ATTR_VALUE)
51                  )
52              );
53              
54              for (Element input: form.select("input")) {
55                  
56                  result.append(
57                      String.format(
58                          "%n    <input name=\"%s\" value=\"%s\" />",
59                          input.attr("name"),
60                          input.attr(INPUT_ATTR_VALUE)
61                      )
62                  );
63                  
64                  mapForms.get(form).add(input);
65              }
66              
67              Collections.reverse(mapForms.get(form));
68          }
69              
70          if (!this.injectionModel.getMediatorUtils().getPreferencesUtil().isParsingForm()) {
71              this.logForms(statusCode, elementsForm, result);
72          } else {
73              this.addForms(elementsForm, result, mapForms);
74          }
75      }
76  
77      private void addForms(Elements elementsForm, StringBuilder result, Map<Element, List<Element>> mapForms) {
78          
79          LOGGER.log(
80              LogLevelUtil.CONSOLE_SUCCESS,
81              "Found {} <form> in HTML body, adding input(s) to requests: {}",
82              elementsForm::size,
83              () -> result
84          );
85          
86          for(Entry<Element, List<Element>> form: mapForms.entrySet()) {
87              for (Element input: form.getValue()) {
88                  if ("get".equalsIgnoreCase(form.getKey().attr(FORM_ATTR_VALUE))) {
89                      this.injectionModel.getMediatorUtils().getParameterUtil().getListQueryString().add(
90                          0,
91                          new SimpleEntry<>(
92                              input.attr("name"),
93                              input.attr(INPUT_ATTR_VALUE)
94                          )
95                      );
96                  } else if ("post".equalsIgnoreCase(form.getKey().attr(FORM_ATTR_VALUE))) {
97                      this.injectionModel.getMediatorUtils().getParameterUtil().getListRequest().add(
98                          0,
99                          new SimpleEntry<>(
100                             input.attr("name"),
101                             input.attr(INPUT_ATTR_VALUE)
102                         )
103                     );
104                 }
105             }
106         }
107     }
108 
109     private void logForms(int statusCode, Elements elementsForm, StringBuilder result) {
110         
111         LOGGER.log(
112             LogLevelUtil.CONSOLE_DEFAULT,
113             "Found {} ignored <form> in HTML body: {}",
114             elementsForm::size,
115             () -> result
116         );
117         
118         if (statusCode != 200) {
119             LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "WAF can detect missing form parameters, you may enable 'Add <input/> parameters' in Preferences and retry");
120         }
121     }
122 }