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