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          var elementsForm = Jsoup.parse(pageSource).select("form");
32          if (elementsForm.isEmpty()) {
33              return;
34          }
35          
36          var result = new StringBuilder();
37          Map<Element, List<Element>> mapForms = new HashMap<>();
38          
39          for (Element form: elementsForm) {
40              mapForms.put(form, new ArrayList<>());
41              result.append(
42                  String.format(
43                      "%n<form action=\"%s\" method=\"%s\" />",
44                      form.attr("action"),
45                      form.attr(FormUtil.FORM_ATTR_VALUE)
46                  )
47              );
48              for (Element input: form.select("input")) {
49                  result.append(
50                      String.format(
51                          "%n    <input name=\"%s\" value=\"%s\" />",
52                          input.attr("name"),
53                          input.attr(FormUtil.INPUT_ATTR_VALUE)
54                      )
55                  );
56                  mapForms.get(form).add(input);
57              }
58              Collections.reverse(mapForms.get(form));
59          }
60              
61          if (!this.injectionModel.getMediatorUtils().getPreferencesUtil().isParsingForm()) {
62              this.logForms(statusCode, elementsForm, result);
63          } else {
64              this.addForms(elementsForm, result, mapForms);
65          }
66      }
67  
68      private void addForms(Elements elementsForm, StringBuilder result, Map<Element, List<Element>> mapForms) {
69          LOGGER.log(
70              LogLevelUtil.CONSOLE_SUCCESS,
71              "Found {} <form> in HTML body, adding input(s) to requests: {}",
72              elementsForm::size,
73              () -> result
74          );
75          
76          for (Entry<Element, List<Element>> form: mapForms.entrySet()) {
77              for (Element input: form.getValue()) {
78                  if (StringUtil.GET.equalsIgnoreCase(form.getKey().attr(FormUtil.FORM_ATTR_VALUE))) {
79                      this.injectionModel.getMediatorUtils().getParameterUtil().getListQueryString().add(
80                          0,
81                          new SimpleEntry<>(
82                              input.attr("name"),
83                              input.attr(FormUtil.INPUT_ATTR_VALUE)
84                          )
85                      );
86                  } else if (StringUtil.POST.equalsIgnoreCase(form.getKey().attr(FormUtil.FORM_ATTR_VALUE))) {
87                      this.injectionModel.getMediatorUtils().getParameterUtil().getListRequest().add(
88                          0,
89                          new SimpleEntry<>(
90                              input.attr("name"),
91                              input.attr(FormUtil.INPUT_ATTR_VALUE)
92                          )
93                      );
94                  }
95              }
96          }
97      }
98  
99      private void logForms(int statusCode, Elements elementsForm, StringBuilder result) {
100         LOGGER.log(
101             LogLevelUtil.CONSOLE_DEFAULT,
102             "Found {} ignored <form> in HTML body: {}",
103             elementsForm::size,
104             () -> result
105         );
106         if (statusCode != 200) {
107             LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "WAF can detect missing form parameters, you may enable 'Add <input/> parameters' in Preferences and retry");
108         }
109     }
110 }