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 }