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
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 }