UML Studio делает это вполне хорошо, по моему опыту, и будет работать в "бесплатном режиме" за маленькими проектами.
Как вы заметили, HttpServletRequest
не имеет метода setParameter. Это сделано умышленно, поскольку класс представляет запрос в том виде, в каком он пришел от клиента, и изменение параметра не будет отражать этого.
Одним из решений является использование класса HttpServletRequestWrapper
, который позволяет обернуть один запрос с другим. Вы можете создать подкласс от него и переопределить метод getParameter
, чтобы вернуть ваше очищенное значение. Затем вы можете передать этот обернутый запрос в chain.doFilter
вместо исходного запроса.
Это немного некрасиво, но это то, что вам следует делать в API сервлета. Если вы попытаетесь передать что-нибудь еще в doFilter
, некоторые контейнеры сервлетов будут жаловаться, что вы нарушили спецификацию, и откажутся обрабатывать это.
Более элегантное решение - больше работы - изменить исходный сервлет / JSP, который обрабатывает параметр, так, чтобы он ожидал атрибут запроса вместо параметра. Фильтр проверяет параметр, очищает его и устанавливает атрибут (используя request.setAttribute
) с очищенным значением. Без подклассов, без спуфинга, но требует изменения других частей вашего приложения.
Напишите простой класс, который выполняет субвычисление HttpServletRequestWrapper
с помощью метода getParameter (), который возвращает очищенную версию ввода. Затем передайте экземпляр своего HttpServletRequestWrapper
в Filter.doChain ()
вместо объекта запроса напрямую.
Для записи, вот класс, который я написал:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public final class XssFilter implements Filter {
static class FilteredRequest extends HttpServletRequestWrapper {
/* These are the characters allowed by the Javascript validation */
static String allowedChars = "+-0123456789#*";
public FilteredRequest(ServletRequest request) {
super((HttpServletRequest)request);
}
public String sanitize(String input) {
String result = "";
for (int i = 0; i < input.length(); i++) {
if (allowedChars.indexOf(input.charAt(i)) >= 0) {
result += input.charAt(i);
}
}
return result;
}
public String getParameter(String paramName) {
String value = super.getParameter(paramName);
if ("dangerousParamName".equals(paramName)) {
value = sanitize(value);
}
return value;
}
public String[] getParameterValues(String paramName) {
String values[] = super.getParameterValues(paramName);
if ("dangerousParamName".equals(paramName)) {
for (int index = 0; index < values.length; index++) {
values[index] = sanitize(values[index]);
}
}
return values;
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new FilteredRequest(request), response);
}
public void destroy() {
}
public void init(FilterConfig filterConfig) {
}
}