总述
本文是关于浏览器安全协议、常见的Web攻击、Cookie机制的总结
- 浏览器安全协议: 什么是SOP/CORS/CSP? CORS协议为什么能保证安全,保证的是浏览器还是服务端的安全?
- 常见的Web攻击:什么是XSS攻击/XSRF攻击,有什么类型,怎么预防
- Cookie的作用是什么,其属性SameSite默认值在2020年发生改变带来的影响是什么?
浏览器安全协议
同源策略SOP
同源策略Same-origin policy:页面安全中最严格、最基础、最核心的安全策略
- DOM层面: 限制了来自不同源的 Javascript脚本对当前DOM对象读和写的操作
- 数据层面: 限制了不同源的站点读取当前站点的 Cookie、Indexdb、 Localstorage等数据。
- 网络层面: 使用Xmlhttprequest和Fetch都是无法直接进行跨域请求的
- 跨域写操作(Cross-origin writes):一般是被允许的链接( links),重定向以及表单提交。
- 跨域资源嵌入(cross- origin embedding):一般是被允许,链接( links),重定向以及表单提交
- 跨域读操作(Cross-origin reads):ー般是不被允许的,但常可以通过內嵌资源来巧妙的进行读取访问。例如,你可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法
但这种限制过于严格,在实际使用中太过约束,所以实际的安全策略有所放宽
-
跨文档消息机制
放松了DOM层面的约束:两个不同源的DOM是不能相互操纵的,但可以比较安全地通信
-
内容安全策略CSP
放松了数据层面的约束:让服务器决定浏览器 能够加载哪些资源 是否能够执行内联 Javascript代码
-
跨域资源共享CORS
放松了网络层面的约束(跨域读操作):进行跨域访问控制, 从而使跨域数据传输得以安全进行
跨域资源共享CORS
为什么CORS机制保证了跨域通信的安全?保证的是浏览器的安全还是服务端的安全?
之前开发时遇到cors,都是想尽一切办法,把浏览器控制台报错干掉,成功拿到数据
但一直没想通:为什么服务端在相应头里加上一句简单的access-control-allow-origin,就可以保证通信安全呢?这样保证了谁的安全呢
cors是浏览器的一套机制,服务端之间的通信是没有这套约束的,所以有人说 cors是为了保护浏览器的安全.但只要恶意站点把自己所有资源都加上这样的响应头,浏览器依旧会拿到恶意数据,这样的机制有什么意义呢?
其实cors的真正意义在于:浏览器保证损恶意攻击的成功,不是它的疏忽造成.
浏览器又叫user agent,用户代理。它作为一个容器,使得【恶意网站+被害用户+目标网站】有了相遇的机会。如果不加限制,恶意网站就可以利用浏览器 去达成攻击。
举个例子,在没有cors机制时,一个恶意网站如何利用浏览器中保存的用户登录凭证cookie,发起一个向fraud帐户的转账请求:
- 在用户登录目标网站victim.com后,目标网站返回一个登录凭证(set-Cookie=‘loginToken=1kqa23m6 ;domain=victim.com;path=/;sameSite:none;secure;’
- 用户不小心进入恶意站点evil.com.通过script脚本发起一个请求.自动发起请求.因为请求的url命中取用规则,cookie被携带上,并且,通过很简单的hack修改了请求头中的referer,从evil.com改为了victim.com
- 最终victim站点中招了
这便是一个CSRF攻击
浏览器对这次攻击有不可推卸的责任.
因为如果没有浏览器,恶意站点即便伪造请求,去修改referer,但是没有用户凭证,服务端不会判定这次请求成功
所以浏览器强制使用cors机制.其中关键在于origin.origin它是不能被用户代码修改的,只由当前所在站点决定,会诚实地告诉被害站点victim.com,本次请求来自evil.com这个恶意站点
然后由victim.com的服务端去校验,如果victim.com没有把evil.comr认做可信任源.那么在刚刚的例子中,这次跨域请求会在preflight预检阶段失败,真正的post转账请求没有发生,损失也就没有造成
所以除了get和表单post这种没有副作用请求,都会有一遍预检流程,而对于没有预检流程的简单请求,如果没有通过cors检查.请求已经发出去了,服务端也正常相应了.只是浏览器认为不安全,做了拦截
处理
-
简单请求
- 请求方法是以下三种方法之一: HEAD GET POST
- 请求头信息不超出以下几种字段Accept/Accept-Language/ content-Language/Last-Event-ID/Content-Type只限于三个值 [application/x-www-form-encoded;multipart/form-data;text/plain]
直接发出CORS请求,在头信息之中,增加一个origin字段说明,本次请求来自哪个源
服务器根据origin决定是否同意:Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。
浏览器检查Access-Control-Allow-Origin >>如果浏览器指定的源Origin,不在许可范围内抛出一个错误,被Xmlhttprequest的onerror回调函数捕获。
-
非简单请求
- 请求方法是PUT 或 DELETE
- 或者Content-Type是application/json
正式通信之前,预检(preflight)浏览器先询问服务器"当前网页所在的域名origin是否许可+以使用哪些方法Access-Control-Request-Method+头信息字段Access-Control-Request-Headers"有得到肯定答复,浏览器オ会发出正式的Xmlhttprequest请求,否则就报错。
预检请求的回应:如果服务器否定了”预检”请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段
浏览器的正式请求和回应:通过了"预检"请求,每次请求,就都跟简单请求一样,会有一个origin头信息字段,响应也都会有一个 Access-Controll-Allow- Origin
跨域携带cookie:
如果要把 Cookie发到服务器,一方面要服务器同意,指定 Access-Controll-Allow-Credentials字段。 另一方面,请求头设置withcredentials属性。
需要注意的是,如果要发送 Cookie, Access-Controll-Allow-Origin就不能设为星号,必须指定明确Origin
表单跨域
史上表单一直可以发出跨域请求即便是更严格的sop协议。为了兼容表单(form), content-type设计如此,AJAX的跨域设计就是,只要表单可以发,AJAX就可以直接发。
两大web攻击
CSRF攻击——Cross-site request forgery
CSRF攻击的两个必要条件
- 拿到用户在目标站点的登录凭证
- 在恶意站点下向目标站点发起请求
为什么可以拿到用户登录凭证:在cookie的sameSite出现之前,cookie被浏览器与URL绑定.即浏览器在evil.com站点向victim.com站点发起请求:victim.com/transfer_to… 因为请求的host和path命中cookie的取用规则(无论是谁发起请求,都会带上cookie ) 这个请求就会带上用户在victim.com网站的登录凭证
如何发起请求:回标站点当然不会把恶意请求植入自己的负面 所以一般是从目标站点打开一个恶意站点,在恶意站点发起请求
类型
自动发起POST请求
自动发起Get请求
引诱用户点击链接
预防
先分析一下出现这种危险的原因:
-
在页面中可以任意引用第三方资源,
-
让XmlhttpRequest和Fetch去跨域请求资源。
便可以找到预防措施了
-
Cookie-Samesite属性
-
CORS-Origin服务端验证请求的来源站点
-
CSRF Token/双重cookie
CSS.攻击——永远不信任用户输入
向HTML文件中注入恶意代码的
危害
-
窃取 Cookie信息
恶意 Javascript可以通过“ document. cookie”获取Cookie信息,然后通过Xmlhttprequest或者Fetch加上CORS功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。
-
监听用户行为
恶意 Javascript可以使用' addeventlistener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情
-
修改DOM
用来欺骗用户输入用户名和密码等信息
在页面内生成浮窗广告
类型
存储型、反射型 和 基于DOM
-
存储型XSS攻击
首先黑客利用站点漏洞将一段恶意 Javascript代码提交到网站的数据库中然后用户向网站请求包含了恶意 Javascript脚本的页面当用户浏览该页面的时候,恶意脚本就会将用户的 Cookie信息等数据上传到服务器。
-
反射型XSS攻击
恶意 Javascript脚本属于用户发送给网站请求中的一部分,随后网站又把恶意 Javascript脚本返回给用户。当恶意 Javascript脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作,黑客经常会通过QQ群或者邮件等渠道诱导用户去点击这些恶意链接
-
基于DOM的XSS攻击
不牵涉到页面Web服务器的黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面传输过程中修改HTML页面的内容,这种劫持类型很多,有通过WiFⅰ路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点是在Web资源传输过程或者在用户使用页面的过程中修改Web 页面的数据。
预防
存储型和反射型都要服务器来处理,这两种类型是服务端的安全漏洞;而基于DOM全部都是在浏览器端完成的,因此是前端的安全漏洞
其过程是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至恶意服务器上
-
阻止恶意消息发送:
-
HttpOnly属性
由于很多XSS攻击都是来盗用 Cookie的,因此还可以通过使用 Httponly .属性来保护我们 Cookie的安全。
-
添加验证码
防止脚本冒充用户提交
-
-
阻止脚本的注入:
-
充分利用CSP
限制加载其他域下的资源文件,这样即使黑客插入了一个 Javascript文件,这个Javascript文件也是无法被加载的(禁止向第三方域提交数据,这样用户数据也不会外泄;禁止执行内联脚本和未授权的脚本;还提供了上报机制,这样可以帮助我们尽快发现有哪些XSS攻击,以便尽快修复问题)
-
服务器对输入脚本进行过滤或转码
原始代码:
code:<script>alert('??xss???')</script>
过滤:
转码:
-
cookie
关于跨站和跨域/跨源
站和域是不同的
同站(same-site)/跨站( cross-site)和第一方( first- party)/第三方( third- party)是等价的。
但是与浏览器同源策略(SOP)中的「同源(same- origin)/跨域( cross- origin)」是完全不同的概念
同站:只要两个URL的eTLD(有效顶级域名)+1相同即可,不需要考虑协议和端口。
例如taobao.com是一个站, www.taobao.com 和 www.baidu.com 是跨站, www.taobao.com 和 static.taobao.com是同站;
.github.io和b.github.io是跨站(注意是跨站)
同源:指两个URL的协议/主机名/端口一致。
同源策略作为浏览器的安全基石,其「同源」判断是比较严格的,同站不一定同源,不同站一定不同源
属性
-
Expire / Max-age >>生命周期
会话cookie: 最简单的,浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。不需要指定过期时间或者有效期值为Max-Age:Session
它都应重新生成并重新发送会话 Cookie,甚至是已经存在的会话 Cookie。此技术有助于防止会话固定攻击( session fixation attacks)_,在该攻击中第三方可以重用用户的会话 >>
持久cookie:生命周期取決于 过期时间( Expires)或 有效期(Max-Age)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Set-Cookie: id=a3fWa; Max-Age=604800;
如果max-Age属性为正数时,浏览器会将其持久化,即写到对应的 Cookie文件中。 当max-Age属性为负数,则表示该 Cookie只是一个会话性 Cookie。 当max-Age为0时,则会立即删除这个 Cookie。
-
Secure/HttpOnly >>限制访问
但即便设置了 Secure标记,敏感信息也不应该通过Cookie传输,因为 Cookie有其固有的不安全性, Secure标记也无法提供确实的安全保障,例如,可以访问客户端硬盘的人可以读取它。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly >>
可以预防(XSS)攻击
-
Domain path/SameSite >>作用域
同决定了cookie何时被浏览器自动添加到请求头部中发送出去
父域名或者父路径都不可以使用
设置:如果不指定,默认值为设置该cookie的网页所在的域名,不能除当前域名或者其父域名之外的其他domain;但不能是公共后缀 public suffix
比如www.baidu.com, domain可以设置为“www.baidu.com”,也可以设置为“baidu.com”,但不能设置为“.com”或“com”。
当前大多数浏览器遵循RFC6265口,设置 Domain时不需要加前导点。浏览器不遵循该规范,则需要加前导点,例如: Domain=,mozi11a.org >>
使用:本域名 与 其子域,如果不指定,默认为origin,但子域名不可用;如果指定了 Domain 为origin,则包含子域名。
例如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如developer.mozilla.org。因此,指定 Domain比省略它的限制要少
设置: 默认为请求 uri 的路径,URL路径必须存在于请求URL中;path 应该以 "/" 结尾
使用: 默认为请求 uri 的路径;当URI的path值是以“/”结尾的时候,直接设置为cookie的path值;当URI的path值不是以“/”结尾的时候,查看path里面是否有“/”;如果有“/”的话,直接截取到最后一个“/”,然后设置为cookie的path值。
如果没有“/”的话,将cookie的path设置为”/”。.但不会像domain那样影响子路径
-
SameSite >>
限制三方/跨站cookie:可以让 Cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击
修改:之前獸认是None的, Chrome80后默认是Lax。
影响:表单,iframe,AJAX,Image 这四种情况从以前的跨站会发送三方 Cookie,变成了不发送
取值
-
Strict仅允许一方请求携带Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页URL与请求目标URL完全一致
-
Lax允许部分第三方请求携带Cookie
-
None无论是否跨站都会发送Cookie
HTTP 接口不支持 SameSite=none;想加 SameSite=none 属性,那么该 Cookie 就必须同时加上 Secure 属性,表示只有在HTTPS 协议下该 Cookie 才会被发送
-
-
Name/Value:用 Javascript操作 Cookie的时候注意对于Value值,最好用encodeURIComponent 对其编码
Cookie前缀:Name 前缀为__ Secure- 或 __Host,只可以应用在使用了安全连接(HTTPS)的域中,需要同时设置 secure以 __Host- 为前缀,path 属性的值必须为 "/" (表示整个站点)不能含有 domain 属性。// 当响应来自于一个安全域(HTTPS)的时候,二者都可以被客户端接受
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/
// 缺少 Secure 指令,会被拒绝
Set-Cookie : __Secure-id=1
// 缺少 Path=/ 指令,会被拒绝
Set-Cookie: __Host-id=1; Secure
// 由于设置了 domain 属性,会被拒绝
Set-Cookie: __Host-id=1; Secure; Path=/; domain=example.com
子域上的易受攻击的应用程序可以使用 Domain属性设置 cookie,从而可以访问所有其他子域上的该 cookie。会话固定攻击中可能会滥用此机制。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!