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().getPreferencesUtil().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().getParameterUtil().getListQueryString().add(
77                          0,
78                          new SimpleEntry<>(
79                              input.attr("name"),
80                              input.attr(FormUtil.INPUT_ATTR_VALUE)
81                          )
82                      );
83                  } else if (StringUtil.POST.equalsIgnoreCase(form.getKey().attr(FormUtil.FORM_ATTR_VALUE))) {
84                      this.injectionModel.getMediatorUtils().getParameterUtil().getListRequest().add(
85                          0,
86                          new SimpleEntry<>(
87                              input.attr("name"),
88                              input.attr(FormUtil.INPUT_ATTR_VALUE)
89                          )
90                      );
91                  }
92              }
93          }
94      }
95  
96      private void logForms(int statusCode, Elements elementsForm, StringBuilder result) {
97          LOGGER.log(
98              LogLevelUtil.CONSOLE_DEFAULT,
99              "Found {} ignored <form> in HTML body: {}",
100             elementsForm::size,
101             () -> result
102         );
103         if (statusCode != 200) {
104             LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "WAF can detect missing form parameters, you may enable 'Add <input/> parameters' in Preferences and retry");
105         }
106     }
107 }