Springboot -- 网络安全漏洞处理

不安全的 HTTP 方法以及 Nginx 屏蔽版本号显示

说明

Web服务器在默认情况下开放了一些不必要的HTTP方法(如OPTIONS,DELETE、PUT、TRACE、MOVE、COPY),增加了受攻击的几率,所以对于我们不需要使用的HTTP方法,要做出尽量限制,避免非法访问的发生。

以 OPTIONS 为例:
其主要用途包括:
1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。
2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。

检测方式

  • 随便挑选一个开发接口,例如我们选取一个用 GET 方式请求的接口。
  • 将请求方式修改为 OPTIONS
  • 查看响应结果
    在这里插入图片描述
    以上的响应结果其实暴露出两个问题:
    1、不安全的 HTTP 方法
    2、nginx 不应该显示版本号

不安全的 HTTP 方法 处理代码

修改 Springboot 内置 Tomcat 的配置

@Configuration
public class TomcatConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {

        TomcatServletWebServerFactory tomcatServletContainerFactory = new TomcatServletWebServerFactory();

        tomcatServletContainerFactory.addContextCustomizers(new TomcatContextCustomizer(){
  
           @Override
           public void customize(Context context) {
            SecurityConstraint constraint = new SecurityConstraint();
            SecurityCollection collection = new SecurityCollection();
            //http方法
            collection.addMethod("PUT");
            collection.addMethod("DELETE");
            collection.addMethod("HEAD");
            collection.addMethod("OPTIONS");
            collection.addMethod("TRACE");
            //url匹配表达式 所有路径
            collection.addPattern("/*");
            constraint.addCollection(collection);
            //设置以上HTTP方法在指定路径下需要身份验证约束
            constraint.setAuthConstraint(true);
            context.addConstraint(constraint );

            //设置使用httpOnly
            context.setUseHttpOnly(true);
           }
        });
        return tomcatServletContainerFactory;
    }
}

屏蔽 Nginx 版本号显示

  • 打开 nginx 主配置文件添加属性:
http {
  server_tokens off;
}
server {
  server_tokens off;
}

点击劫持漏洞

说明

查看HTTP响应头信息中的X-Frame-Options,可以指示浏览器是否应该加载一个iframe中的页面。
防止服务器响应头信息中没有X-Frame-Options,从而存在ClickJacking攻击的风险。

什么是ClickJacking

点击劫持(用户界面补救攻击,UI补救供给,UI攻击)是一种恶意技术,他通过诱骗 Web 用户点击与用户认为他们正在点击的内容不同的东西,从而可能泄露机密信息或控制他们的计算机,同时点击看似无害的网页。
点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在该网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。

检测方式

使用AWVS,我使用的版本是 10.5 ,安装后登录网页 localhost:8183,配置如下:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
查看结果:
显示 X-Frame-Options 响应头丢失
在这里插入图片描述

处理代码

@Component
public class IdentityInterceptor extends HandlerInterceptorAdapter
{

    ......
    
	/**
	 * 在业务处理器处理请求执行完成后,生成视图之前执行的动作 可在modelAndView中加入数据,比如当前时间
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception
	{
		//网络安全要求 增加 x-frame-options 响应头 防止ClickJacking攻击
		response.addHeader("x-frame-options","SAMEORIGIN");
	}
	
    ......
    
}

若是服务由Nginx转发,还需要修改Nginx配置

http{
	add_header X-Frame-Options SAMEORIGIN;
}

或者

server{
	add_header X-Frame-Options SAMEORIGIN;
}

XSS跨站脚本攻击

说明

跨站脚本是一种经常出现在web应用程序中的计算机安全漏洞,是由于web应用对用户提交请求参数未做充分的检查过滤,允许用户在提交的数据中加入HTML\JS代码,未加编码地输出到第三方用户浏览器,恶意攻击者可以利用JS、activeX、html语言甚至flash应用的漏洞,发送恶意代码给另一个用户,因为浏览器无法识别脚本是否可信,从而跨站漏洞脚本便运行并让攻击者获取其他用户信息。

取自百度百科的举例:
用户在浏览网站、使用即时通讯软件、甚至在阅读电子邮件时,通常会点击其中的链接。攻击者通过在链接中插入恶意代码,就能够盗取用户信息。攻击者通常会用十六进制(或其他编码方式)将链接编码,以免用户怀疑它的合法性。网站在接收到包含恶意代码的请求之后会产成一个包含恶意代码的页面,而这个页面看起来就像是那个网站应当生成的合法页面一样。许多流行的留言本和论坛程序允许用户发表包含HTML和javascript的帖子。假设用户甲发表了一篇包含恶意脚本的帖子,那么用户乙在浏览这篇帖子时,恶意脚本就会执行,盗取用户乙的session信息。有关攻击方法的详细情况将在下面阐述。

检测方式

在AWS中检测:
在这里插入图片描述

处理代码 (参考网上的代码,主要是对传入的信息进行敏感字符的过滤)

public final class HttpRequestWrapper extends HttpServletRequestWrapper {
 
    private Map<String, String> xssMap;
     
    public HttpRequestWrapper(HttpServletRequest request) {
        super(request);
    }
 
    public HttpRequestWrapper(HttpServletRequest request,
            Map<String, String> xssMap) {
        super(request);
        this.xssMap = xssMap;
    }
 
    @Override
    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;
    }
 
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return cleanXSS(value);
    }
 
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null)
            return null;
        return cleanXSS(value);
 
    }
 
    /**
     * 清除恶意的XSS脚本
     * 
     * @param value
     * @return
     */
    private String cleanXSS(String value) {
        Set<String> keySet = xssMap.keySet();
        for(String key : keySet){
            String v = xssMap.get(key);
            value = value.replaceAll(key,v);
        }
        return value;
    }
}

/**
 * 防止 XSS 跨站脚本攻击
 */
@Component
public class XSSFilter implements Filter {

    // XSS处理Map
    private static Map<String,String> xssMap = new LinkedHashMap<String,String>();
     
    public void init(FilterConfig filterConfig) throws ServletException {
        // 含有脚本:script
        xssMap.put("[s|S][c|C][r|R][i|C][p|P][t|T]", "");
        // 含有脚本 javascript
        xssMap.put("[\\\"\\\'][\\s]*[j|J][a|A][v|V][a|A][s|S][c|C][r|R][i|I][p|P][t|T]:(.*)[\\\"\\\']", "\"\"");
        // 含有函数: eval
        xssMap.put("[e|E][v|V][a|A][l|L]\\((.*)\\)", "");
        // 含有符号 <
        xssMap.put("<", "&lt;");
        // 含有符号 >
        xssMap.put(">", "&gt;");
        // 含有符号 (
        xssMap.put("\\(", "(");
        // 含有符号 )
        xssMap.put("\\)", ")");
        // 含有符号 '
        xssMap.put("'", "'");
    }
     
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // 强制类型转换 HttpServletRequest
        HttpServletRequest httpReq = (HttpServletRequest)request;
        // 构造HttpRequestWrapper对象处理XSS
        HttpRequestWrapper httpReqWarp = new HttpRequestWrapper(httpReq,xssMap);
        // 
        chain.doFilter(httpReqWarp, response);
 
    }
 
    public void destroy() {
         
    }
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mingvvv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值