跨站请求伪造(CSRF)、主机头攻击、非GET/POST方法预防,一篇就够!

当前在处理系统安全测试缺陷问题时,发现诸多安全问题,记录解决过程和方法,分享共勉。

解释:

CSRF不懂看我历史文章:CSRF

主机头攻击:

在计算机网络中,主机头攻击是一种网络安全攻击方式,它利用了网络协议栈中的缺陷,以伪造的IP地址为源地址向网络发送数据包,目的是在欺骗目标主机,使其认为这些数据包是从指定的合法源发出的,并从而欺骗目标主机执行一些攻击者预期的动作。

主机头攻击通常也被称作IP欺骗(IP Spoofing),攻击者会伪造数据包中的源IP地址,使其看起来像是从合法的主机上发出的,这样就可以避开目标主机的IP地址过滤和安全验证机制,欺骗目标主机执行攻击者的恶意操作,例如进行DDoS攻击等。由于源地址伪造,攻击者通常很难被追踪和识别,所以主机头攻击被广泛应用于各种恶意网络攻击中。

简单讲就是伪造请求地址(请求头中的host)

限制请求方式:

在某些系统安全测试过程中只允许使用GET或POST方法,使用其他的HTTP协议方法可能会导致系统出现异常或崩溃,从而影响测试的结果。而使用GET和POST方法则可以最大程度地保证测试的稳定性和可靠性。

当然最先想到的可以用NGINX处理,让NGINX帮我们代理拦截,主机头攻击用NGINX也可以 。

但是这里尽量花最小钱办最大事,一个拦截器处理。上代码

package com.iot.framework.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;

/**
 * CSRF - Referer 拦截器
 *
 * @author jiangfy
 */
@Component
public class RefererInterceptor extends HandlerInterceptorAdapter {
    /**
     * 白名单
     */
    private String[] refererDomain = new String[]{"asaGsd4MDkxLw==", "aHR0cDovLzIyLjE4MTo4MDkxLw==", "aHR0cDovLzEwL1BnL2luZGV4Lmh0bWw=", "aHR0cDovLsfdsfDo4MDkxLw=="};
    private String[] hostDomain = new String[]{"bG9jYWxob3sfddN0OjE1fdfsMTA1"};
    /**
     * 是否开启referer校验
     */
    private Boolean checkReferer = true;

    /**
     * 是否开启GET / POST校验
     */
    private Boolean checkReqType = true;


    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        if (checkReqType) {
            String method = req.getMethod();
            // 验证非get post请求
            if (!"GET".equals(method) && !"POST".equals(method)) {
                // 禁止非GET和POST请求访问
                resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                resp.getWriter().write("禁止非GET或POST请求访问!");
                return false;
            }
        }
        if (!checkReferer) {
            return true;
        }
        //referer 代表请目标地址
        String referer = req.getHeader("Referer");
        //host 代表请请求地址  请求地址不可变
        String host = req.getHeader("Host");
        String refererEncryUrl;
        String hostEncryUrl;
        boolean r = false;
        boolean h = false;

        if (referer == null || host == null) {
            // 状态置为404
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return false;
        }
        // 判断referer域名是否在白名单中
        if (refererDomain != null) {
            refererEncryUrl = Base64.getEncoder().encodeToString(referer.getBytes());
            for (String rfr : refererDomain) {
                if (rfr.equals(String.valueOf(refererEncryUrl))) {
                    r = true;
                }
            }
        }
        // 判断host请求地址是否在白名单中
        if (hostDomain != null) {
            hostEncryUrl = Base64.getEncoder().encodeToString(host.getBytes());
            for (String hs : hostDomain) {
                if (hs.equals(String.valueOf(hostEncryUrl))) {
                    h = true;
                }
            }
        }
        return r == true && h == true;
    }
}

定义 “referer白名单” 和 “host白名单”,拦截非GET或POST请求。比对请求中的referer和host值与白名单,只有同时符合才允许通过。

注册拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private RefererInterceptor refererInterceptor;
    /**
     * 注册过滤器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(refererInterceptor).addPathPatterns("/**").excludePathPatterns("/", "/login", "/logout");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了防止 Cookie 的请求伪造CSRF攻击,可以在 jQuery 中使用 Token 验证机制来保证请求的合法性。具体步骤如下: 1. 在服务器端生成一个 Token,将 Token 存储在 Cookie 中,并将 Token 返回给客户端。 2. 在客户端发送请求时,将 Token 作为参数或请求一并发送给服务器端。 3. 服务器端验证 Token 的合法性,如果 Token 验证失败,拒绝处理请求。 下面是一个示例代码,演示如何在 jQuery 中使用 Token 验证机制来防止 CSRF 攻击: ```javascript // 在服务器端生成 Token,将 Token 存储在 Cookie 中,并将 Token 返回给客户端 function generate_token() { var token = Math.random().toString(36).substr(2); document.cookie = "csrf_token=" + token; return token; } // 在客户端发送请求时,将 Token 作为参数或请求一并发送给服务器端 function send_request() { var token = get_token(); $.ajax({ url: "process_request.php", type: "POST", data: { data: "request data", csrf_token: token }, headers: { "X-CSRF-Token": token }, success: function(data) { console.log("Request processed"); } }); } // 获取 Cookie 中存储的 Token function get_token() { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); if (cookie.indexOf("csrf_token=") == 0) { return cookie.substring("csrf_token=".length, cookie.length); } } return null; } // 验证 Token 的合法性 function validate_token() { var token = get_token(); if (!token) { return false; } var csrf_token = $("input[name='csrf_token']").val(); if (token != csrf_token) { return false; } return true; } // 处理请求 function process_request() { if (!validate_token()) { console.error("CSRF attack detected"); return; } // 正常处理请求 } // 在页面加载时生成 Token $(document).ready(function() { generate_token(); }); // 绑定按钮点击事件 $("#send_request_button").click(function() { send_request(); }); ``` 上述代码中,使用了 generate_token 函数来在服务器端生成 Token,并将 Token 存储在 Cookie 中。在客户端发送请求时,将 Token 作为参数或请求一并发送给服务器端。在服务器端验证 Token 的合法性时,可以使用 validate_token 函数来实现。如果 Token 验证失败,拒绝处理请求

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值