Web安全之XSS跨站脚本攻击:如何预防及解决

2024-09-07 23:04

本文主要是介绍Web安全之XSS跨站脚本攻击:如何预防及解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 什么是XSS注入

XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,通过注入恶意代码(通常是JavaScript)到目标网站的网页中,以此在用户浏览网页时执行。攻击者可以通过XSS获取用户的敏感信息(如Cookie、会话令牌)或控制用户浏览器的行为,进而造成信息泄露、身份冒用等严重后果。

2. XSS攻击类型

2.1 存储型XSS

存储型XSS 是指攻击者通过输入恶意脚本,存储在服务器端的数据库中。当其他用户从数据库中读取数据时,恶意脚本被执行。

案例示例: 假设一个电商系统允许用户在其个人资料中输入“个人简介”:

<form action="/updateProfile" method="POST"><textarea name="bio" placeholder="Enter your bio"></textarea><button type="submit">Update</button>
</form>

用户提交的个人简介数据被存储在数据库中。如果用户输入恶意脚本:

<script>alert('This is a stored XSS attack');</script>

当其他用户访问该用户的个人资料页面时,这段脚本会被执行。代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>User Profile</title>
</head>
<body><h1>User Profile</h1><div id="bio"><!-- User's bio is rendered here --></div>
</body>
</html>

在这个例子中,bio内容直接插入到HTML中,导致脚本被执行。

防护措施

  • 对用户输入进行HTML转义。
  • 在用户输入内容之前使用输入验证机制。
  • 使用内容安全策略(CSP)来限制执行的脚本来源。

2.2 反射型XSS

反射型XSS 是指攻击者通过构造恶意URL,将其发送给用户。当用户点击这个URL时,恶意脚本被执行。攻击者利用URL中的参数直接在页面上插入恶意代码。

案例示例: 假设电商系统有一个搜索功能,用户可以通过URL中的查询参数来搜索商品:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Search</title>
</head>
<body><h2>Search Results for: <span id="search"></span></h2><script>// 从URL中获取查询参数var searchQuery = new URLSearchParams(window.location.search).get('q');// 直接插入到HTML中document.getElementById('search').innerHTML = searchQuery;</script>
</body>
</html>

如果攻击者通过如下链接引导用户:

http://example.com/search?q=<script>alert('This is a reflected XSS attack');</script>

该脚本会在页面上执行。

防护措施

  • 对所有动态插入到HTML中的内容进行HTML编码。
  • 使用安全的API进行参数插入,如 textContent 替代 innerHTML

2.3 基于DOM的XSS

基于DOM的XSS 是指攻击者通过操控客户端JavaScript,使得恶意脚本被执行。这种攻击不依赖于服务器端,而是通过修改浏览器中运行的JavaScript来实现。

案例示例: 假设电商系统的用户可以通过URL中的查询参数进行商品筛选:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Filter Products</title>
</head>
<body><h2>Filter Results for: <span id="filter"></span></h2><script>// 从URL中获取筛选参数var filterQuery = new URLSearchParams(window.location.search).get('filter');// 直接插入到HTML中document.getElementById('filter').innerHTML = filterQuery;</script>
</body>
</html>

如果攻击者通过如下链接引导用户:

http://example.com/filter?filter=<img src=x onerror=alert('This is a DOM-based XSS attack')>

该脚本会在页面上执行,利用图像加载失败的事件触发XSS攻击。

防护措施

  • 使用适当的JavaScript编码函数,如 textContent 替代 innerHTML
  • 使用现有的库或工具进行XSS防护。
  • 实施内容安全策略(CSP)来限制页面上可执行的脚本。

3. 常见XSS安全问题

3.1 用户输入未经过滤或转义

XSS的根本原因是服务器未对用户输入进行过滤或转义,导致恶意脚本直接在页面中执行。

3.2 动态生成HTML内容

在Java中,动态生成HTML时,如果直接将用户输入嵌入到HTML片段中,而没有进行任何转义,极易造成XSS漏洞。

3.3 在客户端过滤而非服务器端过滤

有些开发者试图通过客户端JavaScript来过滤恶意输入,这是一种非常不安全的做法,因为攻击者可以绕过客户端检查。

4. XSS防护方案

4.1 输入过滤

服务器端应严格过滤用户输入,去除或转义所有不安全的字符。可以通过白名单的方式,确保只允许合法的字符输入。

代码示例

public String filterInput(String input) {return input.replaceAll("[<>]", ""); // 简单的过滤示例
}

4.2 输出编码

对所有动态生成的HTML内容进行输出编码,可以使用HtmlUtils.htmlEscape()或第三方库,如OWASP Java Encoder

代码示例

String safeContent = HtmlUtils.htmlEscape(userInput);

4.3 配置 Spring Security 的 HTTP 头部

CSP是一种浏览器安全机制,通过限制页面中可以执行的脚本,进一步防止XSS攻击。可以在HTTP响应头中配置CSP策略。

Spring Security 提供了对安全头部的支持,可以增强 XSS 防护,尤其是通过启用 Content-Security-Policy(CSP) 和 X-XSS-Protection 等 HTTP 头部。

你可以在 HttpSecurity 中配置安全头部来减少 XSS 攻击的风险:

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.context.annotation.Bean;@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.headers()// 启用X-XSS-Protection头部,阻止浏览器加载XSS攻击的页面.xssProtection().block(true).and()// 启用Content-Security-Policy头部,指定允许的内容源.contentSecurityPolicy("script-src 'self'; object-src 'none';");http.authorizeRequests().anyRequest().authenticated();return http.build();}
}
  • X-XSS-Protection 头部:启用浏览器的 XSS 过滤机制(注意,一些现代浏览器已逐渐弃用此头部)。
  • Content-Security-Policy (CSP) 头部:定义允许的内容源,防止恶意脚本加载。

4.4 验证码防护

对于可能被攻击的表单或重要操作(如登录、评论),引入验证码可以有效防止自动化的XSS攻击脚本。

4.5 统一处理:使用Spring的过滤器

在Spring应用中,使用过滤器(Filter)是一个常见的方式,能够拦截所有HTTP请求,在请求到达控制器之前对请求数据进行统一的XSS防护处理。

实现步骤
  1. 创建XSS过滤器类
    我们可以创建一个自定义的XSSFilter来拦截所有请求,并在其中对请求中的参数进行转义或过滤。

    代码示例

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import java.io.IOException;public class XSSFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化过滤器配置}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 对请求参数进行XSS转义XSSRequestWrapper xssRequestWrapper = new XSSRequestWrapper(request);// 继续请求链chain.doFilter(xssRequestWrapper, response);}@Overridepublic void destroy() {// 销毁时的清理工作}
    }
    
  2. 创建XSSRequestWrapper类
    这个类是对ServletRequest的包装,用于对请求中的所有参数进行过滤或转义。

    代码示例

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import org.springframework.web.util.HtmlUtils;public class XSSRequestWrapper extends HttpServletRequestWrapper {public XSSRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {String value = super.getParameter(name);return HtmlUtils.htmlEscape(value); // 转义HTML特殊字符}@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);if (values == null) {return null;}String[] escapedValues = new String[values.length];for (int i = 0; i < values.length; i++) {escapedValues[i] = HtmlUtils.htmlEscape(values[i]);}return escapedValues;}
    }
    
  3. 注册过滤器
    将自定义的XSSFilter过滤器注册到Spring应用中,这样可以确保所有请求都经过XSS过滤。

    代码示例

    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;@Configuration
    public class FilterConfig {@Beanpublic FilterRegistrationBean<XSSFilter> xssFilterRegistrationBean() {FilterRegistrationBean<XSSFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new XSSFilter());registrationBean.addUrlPatterns("/*");  // 拦截所有URLreturn registrationBean;}
    }
    

通过这种方式,XSS防护被统一处理,开发者无需在每个控制器中显式调用转义函数。这种方式简化了代码,并确保任何输入都经过过滤器的处理。

4.6 统一处理:使用Spring的全局拦截器

除了过滤器,Spring的拦截器(Interceptor)也是一种常用的方式。拦截器通常用于对请求进行全局处理,例如在进入控制器之前对数据进行处理。

实现步骤
  1. 创建XSS拦截器类
    拦截器与过滤器类似,但是它工作在Spring MVC框架的处理链中。我们可以通过实现HandlerInterceptor接口来创建一个全局XSS拦截器。

    代码示例

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.util.HtmlUtils;public class XSSInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 获取请求中的参数并进行XSS转义request.setAttribute("escapedQuery", HtmlUtils.htmlEscape(request.getParameter("query")));return true;}
    }
    
  2. 配置拦截器
    在Spring Boot中,我们可以通过配置类来注册拦截器。

    代码示例

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
    public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册XSS拦截器registry.addInterceptor(new XSSInterceptor()).addPathPatterns("/**");}
    }
    

4.7 比较:过滤器 vs 拦截器

  • 过滤器:工作在Servlet层面,适用于对所有HTTP请求进行预处理,无论是否进入Spring MVC处理器。过滤器通常用于对请求数据进行统一处理,适合对所有请求参数的统一安全处理。
  • 拦截器:工作在Spring MVC处理链中,更适合与Spring框架的集成,可以轻松获取控制器层面的信息,适合应用逻辑的统一处理。

两者在实际应用上都能实现类似的功能,选择使用过滤器还是拦截器,取决于应用的架构设计。如果需要对所有请求统一处理,过滤器是更好的选择;而如果只需对Spring MVC请求做处理,拦截器会更加灵活。

4.8 通过统一异常处理的方式防护XSS

除了拦截器和过滤器,Spring还提供了全局异常处理的机制,通过@ControllerAdvice可以捕获和处理所有控制器中的异常,这也是一种处理非法输入和异常情况的统一方式。

代码示例

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(IllegalArgumentException.class)public ModelAndView handleIllegalArgumentException(IllegalArgumentException e) {// 统一处理非法输入ModelAndView mav = new ModelAndView();mav.addObject("message", "非法输入检测到: " + e.getMessage());mav.setViewName("error");return mav;}
}

通过这种方式,当检测到非法输入时,可以通过抛出异常来触发统一的异常处理逻辑,实现对XSS攻击的防护。

5. 流程图

在这里插入图片描述

6. 总结

XSS是Web应用中最常见的安全漏洞之一,通过合理的输入过滤、输出转义以及CSP等防护手段,可以有效防御此类攻击。在电商交易系统中,无论是用户评论、搜索功能还是其他输入功能,都必须确保安全,防止攻击者通过XSS获取用户信息或劫持用户会话。

这篇关于Web安全之XSS跨站脚本攻击:如何预防及解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146412

相关文章

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏