Spring Security Web : DefaultHttpFirewall HTTP防火墙(缺省模式)

本文介绍了Spring Security提供的防火墙实现,它是缺省实现但默认用严格模式。阐述了其应用的安全规则,如请求非标准化、包含特定字符串序列或斜杠会被拒绝,部分规则可开关设置。还说明了继承关系、使用方法及相关源代码版本和参考文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

功能介绍

DefaultHttpFirewallSpring Security Web提供的一个HTTP防火墙(对应概念模型接口HttpFirewall)实现。该实现是所谓的缺省实现,但实际上Spring Security Web缺省使用的并不是DefaultHttpFirewall,而是严格模式的StrictHttpFirewall。其原因主要是StrictHttpFirewall对安全限制更严格,但是开发人员也可以设置Spring Security Web使用DefaultHttpFirewall

DefaultHttpFirewall所应用的安全规则比较少,主要有:

  1. 如果请求URL不是标准化(normalize)的URL则该请求会被拒绝,以避免安全限制被绕过。

    • 该规则不能被禁用。
    • 仅仅检查servletPathpathInfo部分,不检查contextPath

    这里标准化的URL必须符合以下条件 :
    指定路径中,必须不能包含以下字符串序列之一 :
    ["//","./","/…/","/."]

  2. 如果请求URLURL编码后)包含了斜杠(%2f或者%2F)则该请求会被拒绝。

    通过开关函数setAllowUrlEncodedSlash(boolean) 可以设置是否关闭该规则。缺省使用该规则。

如果请求违反了以上安全规则中的任何一条,DefaultHttpFirewall会通过抛出异常RequestRejectedException拒绝该请求。

继承关系

DefaultHttpFirewall

使用介绍

缺省情况下DefaultHttpFirewall并没有被Spring Security Web使用。如果想使用DefaultHttpFirewall,可以调用FilterChainProxy#setFirewall

源代码

源代码版本 : Spring Security Web 5.1.4.RELEASE

package org.springframework.security.web.firewall;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class DefaultHttpFirewall implements HttpFirewall {
	private boolean allowUrlEncodedSlash;

	@Override
	public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
		FirewalledRequest fwr = new RequestWrapper(request);

		if (!isNormalized(fwr.getServletPath()) || !isNormalized(fwr.getPathInfo())) {
			throw new RequestRejectedException("Un-normalized paths are not supported: " + fwr.getServletPath()
					+ (fwr.getPathInfo() != null ? fwr.getPathInfo() : ""));
		}

		String requestURI = fwr.getRequestURI();
		if (containsInvalidUrlEncodedSlash(requestURI)) {
			throw new RequestRejectedException("The requestURI cannot contain encoded slash. Got " + requestURI);
		}

		return fwr;
	}

	@Override
	public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
		return new FirewalledResponse(response);
	}

	
	public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash) {
		this.allowUrlEncodedSlash = allowUrlEncodedSlash;
	}

	private boolean containsInvalidUrlEncodedSlash(String uri) {
		if (this.allowUrlEncodedSlash || uri == null) {
			return false;
		}

		if (uri.contains("%2f") || uri.contains("%2F")) {
			return true;
		}

		return false;
	}


	private boolean isNormalized(String path) {
		if (path == null) {
			return true;
		}

		for (int j = path.length(); j > 0;) {
			int i = path.lastIndexOf('/', j - 1);
			int gap = j - i;

			if (gap == 2 && path.charAt(i + 1) == '.') {
				// ".", "/./" or "/."
				return false;
			} else if (gap == 3 && path.charAt(i + 1) == '.' && path.charAt(i + 2) == '.') {
				return false;
			}

			j = i;
		}

		return true;
	}

}

参考文章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值