JavaScript复习-前端安全

2022/7/29 JavaScript

# 一、XSS攻击

xss全称为Cross-Site Scripting,跨站脚本攻击

本质:注入恶意代码到网站,并使用户加载执行

目的可能有:

  • 获取当前用户在这个网站的cookie,从而得到用户的敏感信息
  • 以当前用户的身份发起一些非用户本意的操作请求,比如删除网站好友,发帖,发私信等等
  • 实现DDos攻击

xss攻击分为两种类型:非持久性与持久性

# 1.1非持久性攻击

及时性:恶意代码不需要存在数据库中

例如以下示例:

image-20220716160130985
<h1 id="query-id"></h1>
<span>查询结果如下</span>

<script>
	const reg = new RegExp("(^|&)q=([^&]*)(&|$)", "i")
  const res = window.location.search.substr(1).match(reg)
  if (res !== null) {
    const query = decodeURIComponent(res[2])
    document.getElementById('query-key').innerHTML = query
  }
</script>

代码解析:

  • decodeURIComponent()函数可对encodeURIComponent()函数编码的 URI 进行解码
var uri="https://www.runoob.com/my test.php?name=ståle&car=saab";
var uri_encode=encodeURIComponent(uri);
document.write(uri_encode);
document.write(decodeURIComponent(uri_encode));

以上实例输出结果:
https%3A%2F%2Fwww.runoob.com%2Fmy%20test.php%3Fname%3Dst%C3%A5le%26car%3Dsaab
https://www.runoob.com/my test.php?name=ståle&car=saab
  • window.location.search()函数可以从问号 (?) 开始的 URL(查询部分)
image-20220716161410361

现在对该实例进行xss非持久性攻击:

// 恶意代码一
http://abcd.com?q=<script>alert(document.cookie)<script>

// 恶意代码二
http://abcd.com?q=<img scr="" onerror="alert(document.cookie)"/>

如上所示,恶意代码一将不会成功,因为浏览器已经针对script等一些危险标签的插入做了拦截处理

但是恶意代码二能够成功,因为浏览器无法拦截,成功发起了xss非持久性攻击

这段代码是不用存在数据库中,每次执行都会进行一次攻击

# 1.2持久性攻击

将恶意代码存入数据库中

例如用户A是一个黑客,在评论区中输入了一段评论,系统将该段评论存入了数据库中

用户B作为一个普通的用户,访问该评论页面时会出现问题

image-20220716162435980

# 1.3防御

  • 使用HTML转义。对多由外部插入的代码都进行一次转义,将script标签,& < > "" '' /等危险字符都进行过滤和转义替换

  • 尽量避免使用innerHTML、document.write、outerHTML、evel等方法,使用安全性更高的textContent,setAttribute方法

  • 开启CSP保护:在HTTP响应投中设置Content-Security-Policy

Content-Security-Policy: script-src 'self'
// 不允许内联脚本执行
// 禁止加载外域代码
// 禁止外域提交

# 二、 CSRF攻击

CSRF全称为:Cross-site request forgery,跨站请求伪造

流程:

  • 用户登陆目标网站A
  • 用户以某种方式接触到恶意网站B的链接,比如点击广告等等
  • 用户点击链接访问网站B,网站B中的js代码执行,向目标A发送某个请求
  • 由于用户登陆过A网站,因此该请求携带了网站A的相关cookie凭证,最后请求成功

# 2.1实例

例如网站B有以下代码,就会删除用户在A网站的数据

<img src="A.com/delete" style="visibility:hidden">

因为img标签中的src是会自动加载的,所以这段代码会自动执行,但是本身这个这个标签由于设置了visibility,图片并不可见

# 2.2防御

# 2.2.1设置cookie的SameSite属性

image-20220716170043137

设置方法:Set-Cookie: vidget_session=abc123; SameSite=None; Secure

该属性有三个值:

  • Strict:跨站点时,任何情况下都不会发送Cookie,只有当前网页的URL与请求目标一样,才会带上Cookie
  • Lax:大多数情况下不发送第三方Cookie,但是导航到目标网址的Get请求除外,也就是下面这三种方式:
<a href="A.com/delete"></a>
<link rel="prerender" href="A.com/delete"/>
<form method="GET" action="A.com/delete">
  • None:SameSite默认设置为Lax,设置none表示关闭了SameSite

# 2.2.2 CSRF Token

服务端算法生成token,前端保存在localstorage或者sessionstorage中,之后每次请求都需要带上

由于第三方网站无法获取到该token,因此服务端可以识别出来是不是第三方网站的请求

# 2.2.3请求源判断

服务端通过请求头中的Referer和Origin字段,判断请求来源

# 2.2.4二次验证

通过手机验证码、邮箱等进行二次验证

# 三、XS-Leaks

XS-Leaks即跨站泄漏,利用了对HTTP缓存进行查询的机制,通过对资源缓存的判断进而推断出当前用户的相关信息

chrome86版本之前的缓存策略:

  • 用户访问A页面,请求一张图片资源,浏览器拿到这张图片之后,会将这张图片进行缓存,并把这张图片的URL作为缓存查询的键值

  • 用户接着访问B页面,假如这个页面也用到了上述的那张图片,此时浏览器会先查询是否已经缓存了此资源,由于缓存过这张图片,因此浏览器直接使用了缓存资源

由于缓存资源没有域名限制,所有网站都共享了缓存资源

利用这一点就可以检测用户是否访问过特定的网站,恶意网站通过发起特定的资源请求,通过判断此次资源是否来自缓存就可以推断出用户的浏览历史

# 3.1实例

想知道当前访问我们网站的用户是否是A网站昵称为"小a"的用户,可以这么做:

  • 在A网站,将小a的用户头像扒下来,假设地址为http://A.com/user/helloWorld.jpg

  • FETCH POST http://A.com/user/helloWorld.jpg,清除测览器缓存的这张图

  • <link ref=rerender href=" http://A.com/user"/>,强制刷新A网站

  • 请求头像地址,判断其是否来自缓存

  • 如果来自该缓存,则说明该用户就是“小a”

# 3.2防御

  • Cookie设置SameSite,可能能够拦截最后一步:获取资源并判断是否来源于缓存
  • CSRF Token
  • 浏览器支持对缓存资源的分域名管理,让第三方网站无法读取A网站的缓存

# 四、真题

# 4.1百度2020校招Web前端工程师

  • 题目:由于前端直接可被用户访问,攻击者可以轻易得到页面和通讯过程中的相关信息,进而进行恶意的攻击,关于其攻击的方式描述正确的有哪些

  • 选项:

    • 假定站点 foo.com 的服务器架设在公司内网,提供了任意站点截图服务 foo.com/screenshot?url=xxx,恶意修改 url 中的值为内网地址,构成 SSRF 攻击,进而造成数据泄露的风险
    • 网站 foo.com 提供 POST 方法的 /tansfer/to/xxx 的转账服务,由于未做 CSRF 的防范,被攻击者重复伪造该请求,形成重放攻击,造成经济损失
    • 网站 foo.com 使用了非安全的 HTTP 协议,其中转账服务 POST /transfer/to/xxx,转账金额 money 在 payload 上,假定接口层面采用了随机 token 来防范 csrf 攻击,接口参数未做签名校验,此时攻击者通过篡改 money 的数值,构成中间人攻击
    • 借助社会工程学的理论基础,基于用户的贪婪等心理,制作一个 qq.com 的”冒牌”中奖页面,诱导用户输入账号密码进行登录,造成隐私的泄露,属于”钓鱼”的网络欺诈行为
  • 答案:ABCD

SSRF概念:SSRF为服务端请求伪造(Server-Side Request Forgery),指的是攻击者在未能取得服务器所有权限时利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网

SSRF攻击通常针对外部网络无法直接访问的内部系统

原理

很多web应用都提供了从其他的服务器上获取数据的功能。使用指定的URL,web应用便可以获取图片,下载文件,读取文件内容等。SSRF的实质是利用存在缺陷的web应用作为代理攻击远程和本地的服务器。一般情况下, SSRF攻击的目标是外网无法访问的内部系统,黑客可以利用SSRF漏洞获取内部系统的一些信息(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制

攻击方式

攻击者想要访问主机B上的服务,但是由于存在***或者主机B是属于内网主机等原因导致攻击者无法直接访问主机B。而服务器A存在SSRF漏洞,这时攻击者可以借助服务器A来发起SSRF攻击,通过服务器A向主机B发起请求,从而获取主机B的一些信息