0


前端安全汇总(持续更新)

在移动互联网时代,信息安全越来越重要。前端方面也面临着越来越多的安全挑战,本文收集了网上各位大佬的分析总结,将持续整理总结常见的安全问题及其防御措施。

CSRF

CSRF 概念

CSRF

(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证(

cookies

等),绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF 攻击流程

1.受害者登录

a.com

,并保留了登录凭证(

Cookie

)。
2.攻击者引诱受害者访问了

b.com


3.

b.com

a.com

发送了一个请求:

a.com/act=xx

。浏览器会默认携带

a.com

Cookie


4.

a.com

接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
5.

a.com

以受害者的名义执行了

act=xx


6.攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让

a.com

执行了自己定义的操作。

CSRF 攻击类型

GET
GET

类型的

CSRF

利用非常简单,只需要一个

HTTP

请求,一般会这样利用:

<img src="http://bank.example/withdraw?amount=10000&for=hacker" /> 

在受害者访问含有这个

img

的页面后,浏览器会自动向

http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker

发出一次

HTTP

请求。

bank.example

就会收到包含受害者登录信息的一次跨域请求。

POST

这种类型的

CSRF

利用起来通常使用的是一个自动提交的表单,如:

<form action="http://bank.example/withdraw" method="POST"><input type="hidden" name="account" value="xiaoming" /><input type="hidden" name="amount" value="10000" /><input type="hidden" name="for" value="hacker" />
</form>
<script>document.forms[0].submit();
</script> 

访问该页面后,表单会自动提交,相当于模拟用户完成了一次

POST

操作。

POST

类型的攻击通常比

GET

要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许

POST

上面。

链接

链接类型的

CSRF

并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:

<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">重磅消息!!<a
/></a> 

由于之前用户登录了信任的网站

A

,并且保存登录状态,只要用户主动访问上面的这个

PHP

页面,则表示攻击成功。

CSRF 特性

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
  • 跨站请求可以用各种方式:图片 URL超链接CORSForm 提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。

CSRF 防御措施

CSRF

通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对

CSRF

的防护能力来提升安全性。

同源检测

服务器可通过

request headers

origin

referer

两个字段确定请求的来源域。

如果攻击者设置

Referrer Policy

隐藏了

referer

,则建议直接阻止(考虑排除搜索引擎搜索的情况)。

cookie 是不能跨域访问的,为什么还会有 csrf? 浏览器会依据加载的域名附带上对应域名 cookie。如用户在 a 网站登录且生成了授权的 cookies,然后访问 b 网站,b 站故意构造请求 a 站的请求,如删除操作之类的,用不受同源影响的 script,img 或者 iframe 之类的标签加载 a 地址,浏览器会附带上 a 站此登录用户的授权 cookie 信息,这样就构成 crsf,会删除掉当前用户的数据。

Token

CSRF

攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个

CSRF

攻击者无法获取到的

Token

。服务器通过校验请求是否携带正确的

Token

,来把正常的请求和攻击的请求区分开,也可以防范

CSRF

的攻击。

1.将

Token

输出到页面中,对于页面整个

DOM

树中所有的

a

form

标签后都加入

Token


2.页面提交的请求携带这个

Token

3.服务器验证

Token

是否正确

验证码&密码

在关键请求时要求再次输入验证码和密码之类的,打断

csrf

的进程,简单粗暴且有效。

双重 Cookie 验证

利用

CSRF

攻击不能获取到用户

Cookie

的特点,我们可以要求

Ajax

和表单请求携带一个

Cookie

中的值。

1.在用户访问网站页面时,向请求域名注入一个

Cookie

,内容为随机字符串(例如

csrfcookie=v8g9e4ksfhw

)。
2.在前端向后端发起请求时,取出

Cookie

,并添加到

URL

的参数中(接上例

POST
https://www.a.com/comment?csrfcookie=v8g9e4ksfhw

)。
3.后端接口验证

Cookie

中的字段与

URL

参数中的字段是否一致,不一致则拒绝。

Samesite 属性

Chrome 51 开始,浏览器的

Cookie

新增加了一个

SameSite

属性限制第三方

Cookie

,用来防止

CSRF

攻击和用户追踪。

SameSite

根据严格程度取值为

Strict

,

Lax

,

None

目前兼容性及实用性都不太好(不支持子域),暂时不用。

XSS

XSS 概念

Cross-Site Scripting

(跨站脚本攻击)简称

XSS

,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如

Cookie

SessionID

等,进而危害数据安全。

XSS 分类

类型存储区插入点存储型 XSS后端数据库HTML反射型 XSSURLHTMLDOM 型 XSS后端数据库/前端存储/URL前端 JavaScript

存储型 XSS

1.攻击者将恶意代码提交到目标网站的数据库中。
2.用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在

HTML

中返回给浏览器。
3.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

反射型 XSS

1.攻击者构造出特殊的

URL

,其中包含恶意代码。
2.用户打开带有恶意代码的

URL

时,网站服务端将恶意代码从

URL

中取出,拼接在 HTML 中返回给浏览器。
3.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

反射型

XSS

漏洞常见于通过

URL

传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的

URL

才能生效,攻击者往往会结合多种手段诱导用户点击。

DOM 型 XSS

1.攻击者构造出特殊的

URL

,其中包含恶意代码。
2.用户打开带有恶意代码的

URL


3.用户浏览器接收到响应后解析执行,前端

JavaScript

取出

URL

中的恶意代码并执行。
4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM

XSS

跟前两种

XSS

的区别:

DOM

XSS

攻击中,取出和执行恶意代码由浏览器端完成,属于前端

JavaScript

自身的安全漏洞,而其他两种

XSS

都属于服务端的安全漏洞。

XSS 防御

针对攻击者提交恶意代码
输入过滤

对前端而言,输入过滤不可靠。因为一旦攻击者绕过前端过滤,直接构造请求,就可以提交恶意代码了。

输入内容长度控制

对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止

XSS

发生,但可以增加

XSS

攻击的难度。

验证码

防止脚本冒充用户提交危险操作。

针对浏览器执行恶意代码
纯前端渲染

在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(

.innerText

),还是属性(

.setAttribute

),还是样式(

.style

)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。

转义 HTML

应当尽量避免转义

HTML

。但如果不是纯前端渲染,就需要采用合适的转义库,对

HTML

模板各处插入点进行充分的转义。

预防 DOM 型 XSS 攻击

防范存储型和反射型

XSS

是后端

RD

的责任。而

DOM

XSS

攻击不发生在后端。

DOM

XSS

攻击,实际上就是网站前端

JavaScript

代码本身不够严谨,把不可信的数据当作代码执行了。

在使用

.innerHTML

.outerHTML

document.write()

时要特别小心,不要把不可信的数据作为

HTML

插到页面上,而应尽量使用

.textContent

.setAttribute()

等。

如果用

Vue/React

技术栈,并且不使用

v-html/dangerouslySetInnerHTML

功能,就在前端

render

阶段避免

innerHTML、outerHTML

XSS

隐患。

DOM

中的内联事件监听器,如

location、onclick、onerror、onload、onmouseover

等,

<a>

标签的

href

属性,

JavaScript

eval()、setTimeout()、setInterval()

等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些

API

,很容易产生安全隐患,请务必避免。

CSP

内容安全策略 (

CSP

) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (

XSS

) 和数据注入攻击等。

通过

HTTP Header

来定义(优先):

"Content-Security-Policy:" 策略集 

通过

html meta

标签使用:

<meta http-equiv="content-security-policy" content="策略集" /> 

更多策略

  • 禁止加载外域代码,防止复杂的攻击逻辑。
  • 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
  • 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
  • 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
  • 合理使用上报可以及时发现 XSS,利于尽快修复问题。
HttpOnly & Secure
  • cookie 中设置了 HttpOnly 属性,禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie
  • cookie 中设置了 Secure 属性,规定 cookie 只能在 https 协议下才能够发送到服务器。防止信息在传递的过程中被监听捕获后信息泄漏。

iframe 嵌套

点击劫持 (

ClickJacking

) 一般会利用透明

iframe

覆盖原网页诱导用户进行某些操作达成目的。

防止其他页面通过 iframe 引用

//自己网站添加
if (top.location <img src="http://www.baidu.com'; //若被其他网站引用则强制跳" style="margin: auto" />
} 
X-FRAME-OPTIONS

或者添加

HTTP

响应头: X-FRAME-OPTIONS

HTTP

响应头信息中的

X-Frame-Options

,可以指示浏览器是否应该加载一个

iframe

中的页面。如果服务器响应头信息中没有

X-Frame-Options

,则该网站存在

ClickJacking

攻击风险。

防止引用的其他 iframe 篡改自己的页面

添加 sandbox 属性

<iframe src="其他页面.html" frameborder="0" sandbox=""></iframe> 

opener

通过以下两种方式打开的页面可以使用

window.opener

来访问源页面的

window

对象,进而进行篡改原页面:

window.open

window.open('http://www.baidu.com'); 

防御方式:

let newTab = window.open();
newTab.opener = null;
newTab.location = url; 

a 标签加

_blank
<a target="_blank" href="http://www.baidu.com"></a> 

防御方式:

<a target="_blank" href="http://www.baidu.com" rel="noopener noreferrer"></a> 

CDN 劫持

出于性能考虑,前端应用通常会把一些静态资源存放到

CDN

(Content Delivery Networks)上面,例如

js

脚本和

style

文件。这么做可以显著提高前端应用的访问速度,但与此同时却也隐含了一个新的安全风险。如果攻击者劫持了

CDN

,或者对

CDN

中的资源进行了污染,攻击者可以肆意篡改我们的前端页面,对用户实施攻击。

应对流量劫持,前端能做哪些工作?

SRI

SRI 简介

子资源完整性(

SRI

)是允许浏览器检查其获得的资源(例如从

CDN

获得的)是否被篡改的一项安全特性。它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。

通过给

link

标签或者

script

标签增加

integrity

属性即可开启

SRI

功能.

<script type="text/javascript" src="/xxxx/aaa.js" integrity="sha256-xxx sha384-yyy" crossorigin="anonymous"></script> 
integrity

值分成两个部分,第一部分指定哈希值的生成算法(

sha256

sha384

sha512

),第二部分是经过

base64

编码的实际哈希值,两者之间通过一个短横(

-

)分割。

integrity

值可以包含多个由空格分隔的哈希值,只要文件匹配其中任意一个哈希值,就可以通过校验并加载该资源。

crossorigin=“anonymous” 的作用是引入跨域脚本,使用

SRI

要保证资源同域或开启跨域。如果不加此属性则表示不开启 CORS 策略。

浏览器处理 SRI 原理
  • 当浏览器在 script 或者 link 标签中遇到 integrity 属性之后,会在执行脚本或者应用样式表之前对比所加载文件的哈希值和期望的哈希值。
  • 当脚本或者样式表的哈希值和期望的不一致时,浏览器必须拒绝执行脚本或者应用样式表,并且必须返回一个网络错误说明获得脚本或样式表失败。
如何使用 SRI

通过使用

webpack

html-webpack-plugin

webpack-subresource-integrity

可以生成包含

integrity

属性

script

标签。

import SriPlugin from 'webpack-subresource-integrity';

const compiler = webpack({output: {crossOriginLoading: 'anonymous',},plugins: [new SriPlugin({hashFuncNames: ['sha256', 'sha384'],enabled: process.env.NODE_ENV === 'production',}),],
}); 

然后通过插件

script-ext-html-webpack-plugin

script

里注入

onerror

事件和

onsuccess
事件。onerror

事件里再次请求一次数据,比较两次数据是否一致来判断是否被

CDN

劫持。

联合 CSP

另外,通过在

CSP

头部添加:

Content-Security-Policy: require-sri-for script; 

这条指令规定了所有

JavaScript

都要有

integrity

属性,且通过验证才能被加载。

中间人攻击

攻击原理

用户在访问某个网站的时候,在浏览器里却往往直接输入网站域名。浏览器便向网站发起一次

HTTP

请求,在得到一个重定向响应后,再发起一次

HTTPS

请求并得到最终的响应内容。由于在建立起

HTTPS

连接之前存在一次明文的

HTTP

请求和重定向,使得攻击者可以以中间人的方式劫持这次请求,从而进行后续的攻击,例如窃听数据,篡改请求和响应,跳转到钓鱼网站等。

HSTS

HSTS

的全称是

HTTP
Strict-Transport-Security

(严格传输安全),它是一个

Web

安全策略机制,通过服务器设置

HTTP Response Header

告诉浏览器只能通过

HTTPS

访问当前资源,而不是

HTTP

HSTS 语法
Strict-Transport-Security: <max-age=>[; includeSubDomains][; preload] 
  • max-age 是必选参数,是一个以秒为单位的数值,它代表着 HSTS Header 的过期时间,通常设置为 1 年,即 31536000 秒。
  • includeSubDomains 是可选参数,如果包含它,则意味着当前域名及其子域名均开启 HSTS 保护。
  • preload 是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它
HSTS 更多
  • 只要是在有效期内,浏览器都将直接强制性的发起 HTTPS 请求。
  • HSTS 让浏览器强制拒绝不安全的链接,不给用户选择的机会。
  • 第一次访问网站的时候,依然需要一次明文的 HTTP 请求和重定向才能切换到 HTTPS,以及刷新 HSTS 信息,此时仍然可以进行中间人攻击,对此,浏览器里内置一个列表 Preload List,只要是在这个列表里的域名,无论何时、何种情况,浏览器都只使用 HTTPS 发起连接。

cookie secure

通过

cookie
secure

保证你的

session cookie

对于攻击者是不可见的,避免中间人攻击。

其他

HTTPS

HTTPS=HTTP+SSL

确保所有需要的资源都用

HTTPS

引入.

SSL/TLS

传输层安全协议(

Transport Layer Security / TLS

)及其前身安全套接层(

Secure Sockets Layer / SSL

)为浏览器和服务器提供了端到端的加密手段,为互联网通信提供了安全可靠性保障。没有

TLS

,其他安全手段不堪一击。

TLS

HTTP

安全的基石。

Cache Control

指定页面的缓存策略。强烈建议手动指定页面缓存策略,否则会由浏览器和代理来控制是否缓存内容。一个不当的缓存策略可能会导致性能问题和安全问题。

Content Type Options

通常浏览器根据响应头的

Content Type

字段分辨资源类型,但假若某些资源

Content Type

是错的或未定义,浏览器会启用

MIME-sniffing

来猜测该资源的类型,解析内容并执行。

X-Content-Type-Options

响应头可以关闭浏览器的资源

MIME-sniffing

功能:

X-Content-Type-Options: nosniff 

信息泄露

以下都应删除

  • Server Banner 响应头里加入 Server Banner 来标明自己身份和版本号 如:server:nginx/1.10.0 (Ubuntu)
  • Web 框架信息 很多 Web 框架都会设置响应头来标示自己身份、版本。这些响应头都是非标准的,而且也不影响页面渲染,只是为了框架自身的宣传。如:X-Powered-By, X-Runtime, X-Version, X-AspNet-Version

参考链接

  • 前端安全系列(一):如何防止 XSS 攻击?
  • 前端安全系列(二):如何防止 CSRF 攻击?
  • Cookie 的 SameSite 属性
  • 内容安全策略( CSP )
  • 前端安全问题汇总(实战)
  • HSTS 详解
  • 前端监控方案
  • 使用 SRI 解决 CDN 劫持 d502djj%2Fp%2F11660496.html “https://www.cnblogs.com/xd502djj/p/11660496.html”)
  • 前端监控方案
  • 使用 SRI 解决 CDN 劫持
  • HTTP 安全最佳实践## 网络安全工程师(白帽子)企业级学习路线

第一阶段:安全基础(入门)

img

第二阶段:Web渗透(初级网安工程师)

img

第三阶段:进阶部分(中级网络安全工程师)

img

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

学习资源分享

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标签: 前端 安全

本文转载自: https://blog.csdn.net/Innocence_0/article/details/135314408
版权归原作者 程序员负总裁 所有, 如有侵权,请联系我们删除。

“前端安全汇总(持续更新)”的评论:

还没有评论