前端关于网络安全问题

XSS

 

涉及的面试题 什么是XSS攻击?如何预防XSS攻击

1 基础概念

XSS(Cross Site Scripting)攻击全称跨站脚本攻击是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。[百度百科]

XSS指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。
从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

XSS攻击的危害包括:

1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号

2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力

3、盗窃企业重要的具有商业价值的资料

4、非法转账

5、强制发送电子邮件

6、网站挂马

7、控制受害者机器向其它网站发起攻击

2 原因解析
主要原因:
过于信任客户端提交的数据!

解决办法:

不信任客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理后方可进行下一步的操作.

进一步分析:

客户端提交的数据本身就是应用所需的,但是恶心攻击者利用网站对客户端提提交数据的信任,在数据中插入一些符号以及JavaScript代码,那么这些数据就会成为应用代码中给的一部分了,那么攻击者就可以肆无忌惮的展开攻击

因此我们绝对不可信任任何客户端提交的数据


3 类型

持久性(存储型)和非持久性(反射型)

持久型

持久型也就是攻击的代码被写入数据库中,这个攻击危害性很大,如果网站访问量很大的话,就会导致大量正常访问的页面,就会导致大量正常访问页面的用户都受到攻击。

最典型的就是留言板的XSS攻击


例子中只是简单的alert(),但是脚本如果很复杂盗用用户的cookie(接口请求获取),账号密码(DOM查询获取)等操作
这种情况如果前后端都没有做防御的话,这段评论就会被存储到数据库中,这样每个打开这个页面的用户都会被攻击

非持久型

非持久型XSS是指发送请求时,XSS代码出现在请求的URL中,作为参数提交到服务器,服务器解析并响应。响应结果中包含XSS代码,最后浏览器解析并执行,从概念上可以看出,反射型XSS代码首先是出现在URL中,然后需要服务端解析,最后需要浏览器之后XSS代码才能攻击

非持久型相比持久性的危害就小了很多,一般通过修改URL参数的方式加入攻击代码,诱导用户访问链接从而进行攻击

http://www.xxx.com?name=<script>alert(1)</script>
<div>{{name}}<div>这时候的name就会取值为alert(1)
1
2


但是对于这种攻击,Chrome这类大型浏览器就能自动帮用户防御攻击,但是不代表我们就不需要防御此类攻击。

4 防御方法


通常有两种方式用来防御


1 转义字符

首先,对于用户的输入应该是永远不信任的,最普遍的做法就是转义输入输出的内容,对于括号,尖括号,斜杠进行转义

function escape(str) {
  str = str.replace(/&/g, '&amp;')
  str = str.replace(/</g, '&lt;')
  str = str.replace(/>/g, '&gt;')
  str = str.replace(/"/g, '&quto;')
  str = str.replace(/'/g, '&#39;')
  str = str.replace(/`/g, '&#96;')
  str = str.replace(/\//g, '&#x2F;')
  return str
}
1
2
3
4
5
6
7
8
9
10


通过转义可以将攻击代码 变成

// -> &lt;script&gt;alert(1)&lt;&#x2F;script&gt;
escape('<script>alert(1)</script>')

1
2


但是对于显示富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。

const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt;
console.log(html)
1
2
3
4


以上示例使用了 js-xss 来实现,可以看到在输出中保留了 h1 标签且过滤了 script 标签。

2 .CSP


内容安全策略 (CSP) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。

CSP 的主要目标是减少和报告 XSS 攻击 ,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。

CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。

作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行

CSP本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以进行加载和执行,我们只需要配置规则,如何拦截是由浏览器自己实现的,我们可以通过这种方式来尽量减少XSS攻击
开启CSP的方式(如果使用CSP):


1 你可以使用 Content-Security-Policy HTTP头部 来指定你的策略,像这样:

设置HTTP Header中的Content-Security-Policy: policy

2 设置meta标签的方式

meta http-equiv=“Content-Security-Policy” content=“default-src ‘self’; img-src https://*; child-src ‘none’;”>

常见用例(设置HTTP Header来举例):

一个网站管理者想要所有内容均来自站点的同一个源 (不包括其子域名) 只允许加载本站资源

Content-Security-Policy: default-src ‘self’

一个网站管理者允许内容来自信任的域名及其子域名 (域名不必须与CSP设置所在的域名相同)

Content-Security-Policy: default-src ‘self’ *.trusted.com

一个网站管理者允许网页应用的用户在他们自己的内容中包含来自任何源的图片, 但是限制音频或视频需从信任的资源提供者(获得),所有脚本必须从特定主机服务器获取可信的代码.

Content-Security-Policy: default-src ‘self’; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

只允许加载HTTPS协议图片

Content-Security-Policy: img-src https://*

允许加载任何来源框架

Content-Security-Policy: child-src ‘none’

对于这种方式来说,这要开发者配置了正确的规则,那么即使网站存在漏洞,攻击者也不能执行它的攻击代码,而且CSP的兼容性不错.

CSRF


面试题:什么是CSRF攻击?如何防范CSRF攻击

1 基本概念


        CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

2 原理


        原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑也就是完成一次CSRF攻击,受害者必须依次完成两个步骤:
1 .登录受信任的网站,并在本地生成Cookie
2. 在不登出信任网站的情况下,访问危险网站

你也许有疑问:如果我不满足以上两个条件中的一个,我就不会收到CSRF攻击。
的确如此,但是你不能保证以下情况的发生:
1. 你不能保证你登录了一个网站后,不再打开一个tab页面并访问其他页面
2 .你不能保证你关闭浏览器后,你的本地Cookie立刻过期,你的上次会话已经结束.(事实上,关闭浏览器不能结束一个会话,)

3 危害(CSRF可以做什么)


攻击者盗用了你身份,以你的名义发送恶意请求,CSRF能够做的事情:以你的名义发送邮件,盗取你的账号甚至是购买商品,虚拟货币的转账,个人隐私泄露和财产安全
举个例子:

示例一
有一个小小的东西叫cookie大家应该知道,一般用来处理登录等场景,目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录,服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中,服务端就能知道这个用户已经登录过了。知道这个之后,我们来看场景:
1.你准备去清空你的购物车,于是打开了买买买网站www.maimaimai.com,然后登录成功,一看,购物车东西这么少,不行,还得买多点。
2.你在看有什么东西买的过程中,你的好基友发给你一个链接www.nidongde.com,一脸yin笑地跟你说:“你懂的”,你毫不犹豫打开了。
3.你饶有兴致地浏览着www.nidongde.com,谁知这个网站暗地里做了些不可描述的事情!由于没有同源策略的限制,它向www.maimaimai.com发起了请求!聪明的你一定想到上面的话“服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”,这样一来,这个不法网站就相当于登录了你的账号,可以为所欲为了!如果这不是一个买买买账号,而是你的银行账号,那……
这就是传说中的CSRF攻击。

示例二
银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危险网站B,它里面有一段HTML的代码如下:

  <img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>…

1.首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块

为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000” ,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作…

示例三
为了杜绝上面的问题,银行决定改用POST请求完成转账操作。

银行网站A的WEB表单如下:

 

<form action="Transfer.php" method="POST">
    <p>ToBankId: <input type="text" name="toBankId" /></p>
    <p>Money: <input type="text" name="money" /></p>
    <p><input type="submit" value="Transfer" /></p>
  </form>


后台处理页面Transfer.php如下:

 <?php
    session_start();
    if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
    {
        buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
    }
  ?>


危险网站B,仍然只是包含那句HTML代码:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>


示例二中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果…和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了R E Q U E S T 去 获 取 请 求 的 数 据 , 而 _REQUEST去获取请求的数据,而 REQUEST去获取请求的数据,而_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用G E T 和 _GET和 GET和_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。

示例四
经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:

<?php
    session_start();
    if (isset($_POST['toBankId'] && isset($_POST['money']))
    {
        buy_stocks($_POST['toBankId'], $_POST['money']);
    }
  ?>


然而,危险网站B与时俱进,它改了一下代码:

<html>
  <head>
    <script type="text/javascript">
      function steal()
      {
               iframe = document.frames["steal"];
               iframe.document.Submit("transfer");
      }
    </script>
  </head>

  <body "steal()">
    <iframe name="steal" display="none">
      <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
        <input type="hidden" name="toBankId" value="11">
        <input type="hidden" name="money" value="1000">
      </form>
    </iframe>
  </body>
</html>

那么还是会丢失1000块QAQ!!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值