修复JSP中request.getParameter()引发XSS/跨站脚本漏洞的替代方案咨询
request.getParameter() 安全修复方案
request.getParameter本身是JSP/Servlet规范里的原生参数获取方法,本身不存在漏洞,风险来自于直接使用用户可控的输入值,未做校验、转义就投入业务使用,容易引发XSS、SQL注入等安全问题。以下是可落地的修复方案:
- 优先做白名单输入校验
所有获取到的参数都要先匹配业务规则的白名单,不符合规则的直接返回默认值或者拒绝请求。比如你代码里的车辆新旧标识constants.VEH_NEWUSED只能是NEW/USED两个枚举值,车辆品牌只能是预设的品牌列表内的值,产品编码只能是指定格式的字符串,禁止不符合规则的参数进入业务逻辑。 - 封装统一的安全参数获取工具类
把参数的判空、trim、白名单校验、默认值处理逻辑统一封装,避免业务代码重复写校验逻辑,示例实现如下:
你的原有代码可以替换为以下写法:public class SecurityParamUtil { // 安全获取字符串参数 public static String getSafeString(HttpServletRequest request, String paramName, String allowedRegex, String defaultValue) { String raw = request.getParameter(paramName); if (raw == null || raw.trim().isEmpty()) { return defaultValue; } String trimRaw = raw.trim(); // 正则白名单校验不通过返回默认值 if (allowedRegex != null && !trimRaw.matches(allowedRegex)) { return defaultValue; } return trimRaw; } }<% if(appStatusId == AppCon.DECLINED) { // 示例:产品编码只允许大写字母+数字,长度3-10位 String VPC = SecurityParamUtil.getSafeString(request, constants.PRODUCT_CODE, "^[A-Z0-9]{3,10}$", null); } // 示例:车辆品牌只允许中文、字母,长度1-20位 String Make = SecurityParamUtil.getSafeString(request, constants.VEH_MAKE, "^[\\u4e00-\\u9fa5a-zA-Z]{1,20}$", null); // 示例:车辆新旧标识只允许NEW/USED两个枚举值 String NewUsed = SecurityParamUtil.getSafeString(request, constants.VEH_NEWUSED, "^(NEW|USED)$", null); %> - 根据参数使用场景做对应转义
校验后的参数投入使用时,要根据使用场景做对应转义:- 输出到HTML页面时,用JSTL的
<c:out>标签或者成熟转义库的escapeHtml4方法转义,防止XSS攻击 - 拼接SQL语句时,必须使用预编译
PreparedStatement,禁止直接拼接用户输入,防止SQL注入 - 作为命令参数执行时,禁止直接拼接,要用进程构建器的参数列表模式传入
- 输出到HTML页面时,用JSTL的
- 老旧项目快速修复方案
如果项目不方便改整体框架,至少要对每个获取到的参数做判空、trim处理,再配合对应场景的转义,绝对不要直接把未处理的参数值投入业务使用。
内容的提问来源于stack exchange,提问作者codeG
相关产品推荐
相关产品推荐

