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 }