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