关于tomcat,request.getParameterMap修改map值的问题

本文探讨了如何通过继承HttpServletRequestWrapper类来修改HttpServletRequest的getParameterMap数据,并解释了Tomcat中ParameterMap类的锁定机制。通过实例代码演示了如何实现对请求参数的XSS过滤和修改。
网上都是getParameterMap取到的数据不能修改 但是我继承HttpServletRequestWrapper的类竟然修改成功了
看代码:

package com.uniresource.framework.security;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.springframework.web.util.HtmlUtils;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}

@Override
public Map getParameterMap() {
Map map=super.getParameterMap();
Set set=map.keySet();
Iterator iter=set.iterator();
while(iter.hasNext()){
String key=iter.next().toString();
Object obj=map.get(key);
String[] param=(String[])obj;
//String[] newParam=new String[param.length];
for(int i=0;i<param.length;i++){
String s=param[i];
param[i]=HtmlUtils.htmlEscape(s);
//newParam[i]=HtmlUtils.htmlEscape(s);
}
//map.put(key, newParam);
}
/*for(int i=0;i<map.size();i++){
Object obj=map.get(i);
if(obj instanceof String){
System.out.println(obj.toString());
}
}*/
return map;
}
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null)
return null;
return cleanXSS(value);
}
private String cleanXSS(String value) {
//You'll need to remove the spaces from the html entities below
value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "script");
value = HtmlUtils.htmlEscape(value);
return value;
}

}


所以就去查看了下org.apache.catalina.util.ParameterMap的源码 原来我的tomcat中这个类的locked是非锁定的。还是说现在的tomcat这个值都是非锁定状态的。
/*     */ package org.apache.catalina.util;
/* */
/* */ import java.util.HashMap;
/* */ import java.util.Map;
/* */ import org.apache.tomcat.util.res.StringManager;
/* */
/* */ public final class ParameterMap<K, V> extends HashMap<K, V>
/* */ {
/* */ private static final long serialVersionUID = 1L;
/* 101 */ private boolean locked = false;
/* */
/* 129 */ private static final StringManager sm = StringManager.getManager("org.apache.catalina.util");
/* */
/* */ public ParameterMap()
/* */ {
/* */ }
/* */
/* */ public ParameterMap(int initialCapacity)
/* */ {
/* 64 */ super(initialCapacity);
/* */ }
/* */
/* */ public ParameterMap(int initialCapacity, float loadFactor)
/* */ {
/* 78 */ super(initialCapacity, loadFactor);
/* */ }
/* */
/* */ public ParameterMap(Map<K, V> map)
/* */ {
/* 90 */ super(map);
/* */ }
/* */
/* */ public boolean isLocked()
/* */ {
/* 109 */ return this.locked;
/* */ }
/* */
/* */ public void setLocked(boolean locked)
/* */ {
/* 121 */ this.locked = locked;
/* */ }
/* */
/* */ public void clear()
/* */ {
/* 145 */ if (this.locked) {
/* 146 */ throw new IllegalStateException(sm.getString("parameterMap.locked"));
/* */ }
/* 148 */ super.clear();
/* */ }
/* */
/* */ public V put(K key, V value)
/* */ {
/* 169 */ if (this.locked) {
/* 170 */ throw new IllegalStateException(sm.getString("parameterMap.locked"));
/* */ }
/* 172 */ return super.put(key, value);
/* */ }
/* */
/* */ public void putAll(Map<? extends K, ? extends V> map)
/* */ {
/* 189 */ if (this.locked) {
/* 190 */ throw new IllegalStateException(sm.getString("parameterMap.locked"));
/* */ }
/* 192 */ super.putAll(map);
/* */ }
/* */
/* */ public V remove(Object key)
/* */ {
/* 210 */ if (this.locked) {
/* 211 */ throw new IllegalStateException(sm.getString("parameterMap.locked"));
/* */ }
/* 213 */ return super.remove(key);
/* */ }
/* */ }

/* Location: E:\apache-tomcat-7.0.30\lib\catalina.jar
* Qualified Name: org.apache.catalina.util.ParameterMap
* Java Class Version: 6 (50.0)
* JD-Core Version: 0.5.3
*/
package com.ruoyi.common.utils; import cn.hutool.core.convert.Convert; import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HttpStatus; import com.ruoyi.common.constant.Constants; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.URLDecoder; import java.net.URLEncoder; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * 客户端工具类 * * @author ruoyi */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class ServletUtils extends ServletUtil { /** * 获取String参数 */ public static String getParameter(String name) { return getRequest().getParameter(name); } /** * 获取String参数 */ public static String getParameter(String name, String defaultValue) { return Convert.toStr(getRequest().getParameter(name), defaultValue); } /** * 获取Integer参数 */ public static Integer getParameterToInt(String name) { return Convert.toInt(getRequest().getParameter(name)); } /** * 获取Integer参数 */ public static Integer getParameterToInt(String name, Integer defaultValue) { return Convert.toInt(getRequest().getParameter(name), defaultValue); } /** * 获取Boolean参数 */ public static Boolean getParameterToBool(String name) { return Convert.toBool(getRequest().getParameter(name)); } /** * 获取Boolean参数 */ public static Boolean getParameterToBool(String name, Boolean defaultValue) { return Convert.toBool(getRequest().getParameter(name), defaultValue); } /** * 获得所有请求参数 * * @param request 请求对象{@link ServletRequest} * @return Map */ public static Map<String, String[]> getParams(ServletRequest request) { final Map<String, String[]> map = request.getParameterMap(); return Collections.unmodifiableMap(map); } /** * 获得所有请求参数 * * @param request 请求对象{@link ServletRequest} * @return Map */ /*public static Map<String, String> getParamMap(ServletRequest request) { Map<String, String> params = new HashMap<>(); for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) { params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR)); } return params; }*/ /** * 获取request */ public static HttpServletRequest getRequest() { return getRequestAttributes().getRequest(); } /** * 获取response */ public static HttpServletResponse getResponse() { return getRequestAttributes().getResponse(); } /** * 获取session */ public static HttpSession getSession() { return getRequest().getSession(); } public static ServletRequestAttributes getRequestAttributes() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return (ServletRequestAttributes) attributes; } /** * 将字符串渲染到客户端 * * @param response 渲染对象 * @param string 待渲染的字符串 */ public static void renderString(HttpServletResponse response, String string) { try { response.setStatus(HttpStatus.HTTP_OK); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } } /** * 是否是Ajax异步请求 * * @param request */ public static boolean isAjaxRequest(HttpServletRequest request) { String accept = request.getHeader("accept"); if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) { return true; } String xRequestedWith = request.getHeader("X-Requested-With"); if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) { return true; } String uri = request.getRequestURI(); if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) { return true; } String ajax = request.getParameter("__ajax"); return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml"); } public static String getClientIP() { return getReqIp(getRequest()); } public static String getReqIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (StringUtils.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip) && StringUtils.contains(ip, ",")) { // 多次反向代理后会有多个IP,第一个为真实IP。 ip = StringUtils.substringBefore(ip, ","); } // 处理localhost访问 if (StringUtils.isBlank(ip) || "unkown".equalsIgnoreCase(ip) || StringUtils.split(ip, ".").length != 4) { try { InetAddress inetAddress = InetAddress.getLocalHost(); ip = inetAddress.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } return ip; } /** * 内容编码 * * @param str 内容 * @return 编码后的内容 */ public static String urlEncode(String str) { try { return URLEncoder.encode(str, Constants.UTF8); } catch (UnsupportedEncodingException e) { return StringUtils.EMPTY; } } /** * 内容解码 * * @param str 内容 * @return 解码后的内容 */ public static String urlDecode(String str) { try { return URLDecoder.decode(str, Constants.UTF8); } catch (UnsupportedEncodingException e) { return StringUtils.EMPTY; } } } // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package cn.hutool.extra.servlet; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.bean.copier.ValueProvider; import cn.hutool.core.collection.ArrayIter; import cn.hutool.core.collection.IterUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.MapUtil; import cn.hutool.core.net.NetUtil; import cn.hutool.core.net.multipart.MultipartFormData; import cn.hutool.core.net.multipart.UploadSetting; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.Writer; import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletUtil { public static final String METHOD_DELETE = "DELETE"; public static final String METHOD_HEAD = "HEAD"; public static final String METHOD_GET = "GET"; public static final String METHOD_OPTIONS = "OPTIONS"; public static final String METHOD_POST = "POST"; public static final String METHOD_PUT = "PUT"; public static final String METHOD_TRACE = "TRACE"; public ServletUtil() { } public static Map<String, String[]> getParams(ServletRequest request) { Map<String, String[]> map = request.getParameterMap(); return Collections.unmodifiableMap(map); } public static Map<String, String> getParamMap(ServletRequest request) { Map<String, String> params = new HashMap(); for(Map.Entry<String, String[]> entry : getParams(request).entrySet()) { params.put(entry.getKey(), ArrayUtil.join(entry.getValue(), ",")); } return params; } public static String getBody(ServletRequest request) { try (BufferedReader reader = request.getReader()) { String var3 = IoUtil.read(reader); return var3; } catch (IOException e) { throw new IORuntimeException(e); } } public static byte[] getBodyBytes(ServletRequest request) { try { return IoUtil.readBytes(request.getInputStream()); } catch (IOException e) { throw new IORuntimeException(e); } } public static <T> T fillBean(final ServletRequest request, T bean, CopyOptions copyOptions) { final String beanName = StrUtil.lowerFirst(bean.getClass().getSimpleName()); return (T)BeanUtil.fillBean(bean, new ValueProvider<String>() { public Object value(String key, Type valueType) { String[] values = request.getParameterValues(key); if (ArrayUtil.isEmpty(values)) { values = request.getParameterValues(beanName + "." + key); if (ArrayUtil.isEmpty(values)) { return null; } } return 1 == values.length ? values[0] : values; } public boolean containsKey(String key) { return null != request.getParameter(key) || null != request.getParameter(beanName + "." + key); } }, copyOptions); } public static <T> T fillBean(ServletRequest request, T bean, boolean isIgnoreError) { return (T)fillBean(request, bean, CopyOptions.create().setIgnoreError(isIgnoreError)); } public static <T> T toBean(ServletRequest request, Class<T> beanClass, boolean isIgnoreError) { return (T)fillBean(request, ReflectUtil.newInstanceIfPossible(beanClass), isIgnoreError); } public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) { String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; if (ArrayUtil.isNotEmpty(otherHeaderNames)) { headers = (String[])ArrayUtil.addAll(new String[][]{headers, otherHeaderNames}); } return getClientIPByHeader(request, headers); } public static String getClientIPByHeader(HttpServletRequest request, String... headerNames) { for(String header : headerNames) { String ip = request.getHeader(header); if (!NetUtil.isUnknown(ip)) { return NetUtil.getMultistageReverseProxyIp(ip); } } String ip = request.getRemoteAddr(); return NetUtil.getMultistageReverseProxyIp(ip); } public static MultipartFormData getMultipart(ServletRequest request) throws IORuntimeException { return getMultipart(request, new UploadSetting()); } public static MultipartFormData getMultipart(ServletRequest request, UploadSetting uploadSetting) throws IORuntimeException { MultipartFormData formData = new MultipartFormData(uploadSetting); try { formData.parseRequestStream(request.getInputStream(), CharsetUtil.charset(request.getCharacterEncoding())); return formData; } catch (IOException e) { throw new IORuntimeException(e); } } public static Map<String, String> getHeaderMap(HttpServletRequest request) { Map<String, String> headerMap = new HashMap(); Enumeration<String> names = request.getHeaderNames(); while(names.hasMoreElements()) { String name = (String)names.nextElement(); headerMap.put(name, request.getHeader(name)); } return headerMap; } public static Map<String, List<String>> getHeadersMap(HttpServletRequest request) { Map<String, List<String>> headerMap = new LinkedHashMap(); Enumeration<String> names = request.getHeaderNames(); while(names.hasMoreElements()) { String name = (String)names.nextElement(); headerMap.put(name, ListUtil.list(false, request.getHeaders(name))); } return headerMap; } public static Map<String, Collection<String>> getHeadersMap(HttpServletResponse response) { Map<String, Collection<String>> headerMap = new HashMap(); for(String name : response.getHeaderNames()) { headerMap.put(name, response.getHeaders(name)); } return headerMap; } public static String getHeaderIgnoreCase(HttpServletRequest request, String nameIgnoreCase) { Enumeration<String> names = request.getHeaderNames(); while(names.hasMoreElements()) { String name = (String)names.nextElement(); if (name != null && name.equalsIgnoreCase(nameIgnoreCase)) { return request.getHeader(name); } } return null; } public static String getHeader(HttpServletRequest request, String name, String charsetName) { return getHeader(request, name, CharsetUtil.charset(charsetName)); } public static String getHeader(HttpServletRequest request, String name, Charset charset) { String header = request.getHeader(name); return null != header ? CharsetUtil.convert(header, CharsetUtil.CHARSET_ISO_8859_1, charset) : null; } public static boolean isIE(HttpServletRequest request) { String userAgent = getHeaderIgnoreCase(request, "User-Agent"); if (!StrUtil.isNotBlank(userAgent)) { return false; } else { userAgent = userAgent.toUpperCase(); return userAgent.contains("MSIE") || userAgent.contains("TRIDENT"); } } public static boolean isGetMethod(HttpServletRequest request) { return "GET".equalsIgnoreCase(request.getMethod()); } public static boolean isPostMethod(HttpServletRequest request) { return "POST".equalsIgnoreCase(request.getMethod()); } public static boolean isMultipart(HttpServletRequest request) { if (!isPostMethod(request)) { return false; } else { String contentType = request.getContentType(); return StrUtil.isBlank(contentType) ? false : contentType.toLowerCase().startsWith("multipart/"); } } public static Cookie getCookie(HttpServletRequest httpServletRequest, String name) { return (Cookie)readCookieMap(httpServletRequest).get(name); } public static Map<String, Cookie> readCookieMap(HttpServletRequest httpServletRequest) { Cookie[] cookies = httpServletRequest.getCookies(); return ArrayUtil.isEmpty(cookies) ? MapUtil.empty() : IterUtil.toMap(new ArrayIter(httpServletRequest.getCookies()), new CaseInsensitiveMap(), Cookie::getName); } public static void addCookie(HttpServletResponse response, Cookie cookie) { response.addCookie(cookie); } public static void addCookie(HttpServletResponse response, String name, String value) { response.addCookie(new Cookie(name, value)); } public static void addCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds, String path, String domain) { Cookie cookie = new Cookie(name, value); if (domain != null) { cookie.setDomain(domain); } cookie.setMaxAge(maxAgeInSeconds); cookie.setPath(path); addCookie(response, cookie); } public static void addCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) { addCookie(response, name, value, maxAgeInSeconds, "/", (String)null); } public static PrintWriter getWriter(HttpServletResponse response) throws IORuntimeException { try { return response.getWriter(); } catch (IOException e) { throw new IORuntimeException(e); } } public static void write(HttpServletResponse response, String text, String contentType) { response.setContentType(contentType); Writer writer = null; try { writer = response.getWriter(); writer.write(text); writer.flush(); } catch (IOException e) { throw new UtilException(e); } finally { IoUtil.close(writer); } } public static void write(HttpServletResponse response, File file) { String fileName = file.getName(); String contentType = (String)ObjectUtil.defaultIfNull(FileUtil.getMimeType(fileName), "application/octet-stream"); BufferedInputStream in = null; try { in = FileUtil.getInputStream(file); write(response, in, contentType, fileName); } finally { IoUtil.close(in); } } public static void write(HttpServletResponse response, InputStream in, String contentType, String fileName) { String charset = (String)ObjectUtil.defaultIfNull(response.getCharacterEncoding(), "UTF-8"); String encodeText = URLUtil.encodeAll(fileName, CharsetUtil.charset(charset)); response.setHeader("Content-Disposition", StrUtil.format("attachment;filename=\"{}\";filename*={}''{}", new Object[]{encodeText, charset, encodeText})); response.setContentType(contentType); write(response, in); } public static void write(HttpServletResponse response, InputStream in, String contentType) { response.setContentType(contentType); write(response, in); } public static void write(HttpServletResponse response, InputStream in) { write(response, in, 8192); } public static void write(HttpServletResponse response, InputStream in, int bufferSize) { ServletOutputStream out = null; try { out = response.getOutputStream(); IoUtil.copy(in, out, bufferSize); } catch (IOException e) { throw new UtilException(e); } finally { IoUtil.close(out); IoUtil.close(in); } } public static void setHeader(HttpServletResponse response, String name, Object value) { if (value instanceof String) { response.setHeader(name, (String)value); } else if (Date.class.isAssignableFrom(value.getClass())) { response.setDateHeader(name, ((Date)value).getTime()); } else if (!(value instanceof Integer) && !"int".equalsIgnoreCase(value.getClass().getSimpleName())) { response.setHeader(name, value.toString()); } else { response.setIntHeader(name, (Integer)value); } } } 这里使用的javax怎么办?
07-10
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值