一、浏览器安全
首先了解前端web安全知识,比不可绕开的基础就是同源策略了,同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现。
同源策略的定义(MDN):如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。
在浏览器中,script、img、iframe、link等标签都可以跨域加载资源,而不受同源策略的限制。这些带“src”属性的标签每次加载时,实际上是由浏览器发起了一次GET请求。不同于XMLHttpRequest的是,通过src属性加载的资源,浏览器限制了JavaScript的权限,使其不能读、写返回的内容。
对于XMLHttpRequest来说,它可以访问来自同源对象的内容。但XMLHttpRequest受到同源策略的约束,不能跨域访问资源,在AJAX应用的开发中尤其需要注意这一点。如果XMLHttpRequest能够跨域访问资源,则可能会导致一些敏感数据泄露,比如CSRF的token,从而导致发生安全问题。但是互联网是开放的,随着业务的发展,跨域请求的需求越来越迫切,因此W3C委员会制定了XMLHttpRequest跨域访问标准。它需要通过目标域返回的HTTP头来授权是否允许跨域访问,因为HTTP头对于JavaScript来说一般是无法控制的,所以认为这个方案可以实施。注意:这个跨域访问方案的安全基础就是信任“JavaScript无法控制该HTTP头”,如果此信任基础被打破,则此方案也将不再安全。
浏览器沙箱
在网页中插入一段恶意代码,利用浏览器漏洞执行任意代码的攻击方式,在黑客圈子里被形象地称为“挂马”,“挂马”是浏览器需要面对的一个主要威胁。近年来,独立于杀毒软件之外,浏览器厂商根据挂马的特点研究出了一些对抗挂马的技术。比如在Windows系统中,浏览器密切结合DEP、ASLR、SafeSEH等操作系统提供的保护技术,对抗内存攻击。与此同时,浏览器还发展出了多进程架构,从安全性上有了很大的提高。
浏览器的多进程架构,将浏览器的各个功能模块分开,各个浏览器实例分开,当一个进程崩溃时,也不会影响到其他的进程。Google Chrome是第一个采取多进程架构的浏览器。Google Chrome的主要进程分为:浏览器进程、渲染进程、插件进程、扩展进程。插件进程如flash、java、pdf等与浏览器进程严格隔离,因此不会互相影响。
渲染引擎由Sandbox隔离,网页代码要与浏览器内核进程通信、与操作系统通信都需要通过IPC channel,在其中会进行一些安全检查。Sandbox即沙箱,计算机技术发展到今天,Sandbox已经成为泛指“资源隔离类模块”的代名词。Sandbox的设计目的一般是为了让不可信任的代码运行在一定的环境中,限制不可信任的代码访问隔离区之外的资源。如果一定要跨越Sandbox边界产生数据交换,则只能通过指定的数据通道,比如经过封装的API来完成,在这些API中会严格检查请求的合法性。
二、跨站脚本攻击XSS
XSS的定义:
跨站脚本攻击,英文全称是Cross Site Script,本来缩写是CSS,但是为了和层叠样式表(Cascading Style Sheet, CSS)有所区别,所以在安全领域叫做“XSS”。
XSS攻击,通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。在一开始,这种攻击的演示案例是跨域的,所以叫做“跨站脚本”。但是发展到今天,由于JavaScript的强大功能以及网站前端应用的复杂化,是否跨域已经不再重要。但是由于历史原因,XSS这个名字却一直保留下来。
XSS根据效果的不同可以分成如下几类。
第一种类型:反射型XSS
反射型XSS只是简单地把用户输入的数据“反射”给浏览器。也就是说,黑客往往需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型XSS也叫做“非持久型XSS”(Non-persistent XSS)。
反射型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。
POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。
如何防范反射型XSS攻击:
对字符串进行编码。
第二种类型:存储型XSS
存储型XSS会把用户输入的数据“存储”在服务器端。这种XSS具有很强的稳定性。比较常见的一个场景就是,黑客写下一篇包含有恶意JavaScript代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码。黑客把恶意的脚本保存到服务器端,所以这种XSS攻击就叫做“存储型XSS”。存储型XSS通常也叫做“持久型XSS”(Persistent XSS),因为从效果上来说,它存在的时间是比较长的。
恶意脚本永久存储在目标服务器上。当浏览器请求数据时,脚本从服务器传回并执行,影响范围比反射型和DOM型XSS更大。存储型XSS攻击的原因仍然是没有做好数据过滤:前端提交数据至服务端时,没有做好过滤;服务端在接受到数据时,在存储之前,没有做过滤;前端从服务端请求到数据,没有过滤输出。
存储型 XSS 的攻击步骤:
- 攻击者将恶意代码提交到目标网站的数据库中。
- 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
如何防范存储型XSS攻击:
- 前端数据传递给服务器之前,先转义/过滤(防范不了抓包修改数据的情况)
- 服务器接收到数据,在存储到数据库之前,进行转义/过滤
- 前端接收到服务器传递过来的数据,在展示到页面前,先进行转义/过滤
- 查看存储型XSS攻击示例(根据Readme提示查看)
除了谨慎的转义,我们还需要其他一些手段来防范XSS攻击:
1.Content Security Policy
在服务端使用 HTTP的 Content-Security-Policy 头部来指定策略,或者在前端设置 meta 标签。
例如下面的配置只允许加载同域下的资源:
Content-Security-Policy: default-src 'self'
<meta http-equiv="Content-Security-Policy" content="form-action 'self';">
前端和服务端设置 CSP 的效果相同,但是meta无法使用report
严格的 CSP 在 XSS 的防范中可以起到以下的作用:
- 禁止加载外域代码,防止复杂的攻击逻辑。
- 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
- 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
- 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
- 合理使用上报可以及时发现 XSS,利于尽快修复问题
2.输入内容长度控制
对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。
3.输入内容限制
对于部分输入,可以限定不能包含特殊字符或者仅能输入数字等。
4.其他安全措施
- HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- 验证码:防止脚本冒充用户提交危险操作。
第三种类型:DOM Based XSS
实际上,这种类型的XSS并非按照“数据是否保存在服务器端”来划分,DOMBased XSS从效果上来说也是反射型XSS。单独划分出来,是因为DOM BasedXSS的形成原因比较特别,发现它的安全专家专门提出了这种类型的XSS。出于历史原因,也就把它单独作为一个分类了。通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS
DOM 型 XSS 攻击,实际上就是前端 JavaScript 代码不够严谨,把不可信的内容插入到了页面。在使用 .innerHTML、.outerHTML、.appendChild、document.write()等API时要特别小心,不要把不可信的数据作为 HTML 插到页面上,尽量使用 .innerText、.textContent、.setAttribute() 等。
DOM 型 XSS 的攻击步骤:
- 攻击者构造出特殊数据,其中包含恶意代码。
- 用户浏览器执行了恶意代码。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
如何防范 DOM 型 XSS 攻击
防范 DOM 型 XSS 攻击的核心就是对输入内容进行转义(DOM 中的内联事件监听器和链接跳转都能把字符串作为代码运行,需要对其内容进行检查)。
- 对于url链接(例如图片的src属性),那么直接使用 encodeURIComponent 来转义。
- 非url,我们可以这样进行编码:
function encodeHtml(str) {
return str.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞。
XSS攻击进阶
前文谈到了XSS的几种分类。接下来,就从攻击的角度来体验一下XSS的威力。XSS攻击成功后,攻击者能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为“XSSPayload”。
XSS Payload实际上就是JavaScript脚本(还可以是Flash或其他富客户端的脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到。一个最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie劫持”攻击。Cookie中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。换句话说,攻击者可以不通过密码,而直接登录进用户的账户。
“Cookie劫持”并非所有的时候都会有效。有的网站可能会在Set-Cookie时给关键Cookie植入HttpOnly标识;有的网站则可能会把Cookie与客户端IP绑定,从而使得XSS窃取的Cookie失去意义。
三、跨站点请求伪造(CSRF)
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
典型的CSRF攻击流程:
- 受害者登录A站点,并保留了登录凭证(Cookie)。
- 攻击者诱导受害者访问了站点B。
- 站点B向站点A发送了一个请求,浏览器会默认携带站点A的Cookie信息。
- 站点A接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是无辜的受害者发送的请求。
- 站点A以受害者的名义执行了站点B的请求。
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者完成了攻击。
CSRF的特点
- 攻击通常在第三方网站发起,如图上的站点B,站点A无法防止攻击发生。
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;并不会去获取cookie信息(cookie有同源策略)
- 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等(来源不明的链接,不要点击)
CSRF 攻击防御
-
添加验证码(体验不好)
验证码能够防御CSRF攻击,但是我们不可能每一次交互都需要验证码,否则用户的体验会非常差,但是我们可以在转账,交易等操作时,增加验证码,确保我们的账户安全。
-
判断请求的来源:检测Referer(并不安全,Referer可以被更改)
Referer Check在互联网中最常见的应用就是“防止图片盗链”。同理,RefererCheck也可以被用于检查请求是否来自合法的“源”
常见的互联网应用,页面与页面之间都具有一定的逻辑关系,这就使得每个正常请求的Referer具有一定的规律。比如一个“论坛发帖”的操作,在正常情况下需要先登录到用户后台,或者访问有发帖功能的页面。在提交“发帖”的表单时,Referer的值必然是发帖表单所在的页面。如果Referer的值不是这个页面,甚至不是发帖网站的域,则极有可能是CSRF攻击。
即使我们能够通过检查Referer是否合法来判断用户是否被CSRF攻击,也仅仅是满足了防御的充分条件。Referer Check的缺陷在于,服务器并非什么时候都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer的发送。在某些情况下,浏览器也不会发送Referer,比如从HTTPS跳转到HTTP,出于安全的考虑,浏览器也不会发送Referer。
`Referer` 可以作为一种辅助手段,来判断请求的来源是否是安全的,但是鉴于 `Referer` 本身是可以被修改的,因为不能仅依赖于 `Referer`
-
使用Token(主流)
CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开。跟验证码类似,只是用户无感知。
- 服务端给用户生成一个token,加密后传递给用户
- 用户在提交请求时,需要携带这个token
- 服务端验证token是否正确
-
Samesite Cookie属性
为了从源头上解决这个问题,Google起草了一份草案来改进HTTP协议,为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值,分别是 Strict 和 Lax。
部署简单,并能有效防御CSRF攻击,但是存在兼容性问题。
Samesite=Strict
Samesite=Strict 被称为是严格模式,表明这个 Cookie 在任何情况都不可能作为第三方的 Cookie,有能力阻止所有CSRF攻击。此时,我们在B站点下发起对A站点的任何请求,A站点的 Cookie 都不会包含在cookie请求头中。
**Samesite=Lax**
`Samesite=Lax` 被称为是宽松模式,与 Strict 相比,放宽了限制,允许发送安全 HTTP 方法带上 Cookie,如 `Get` / `OPTIONS` 、`HEAD` 请求.
但是不安全 HTTP 方法,如: `POST`, `PUT`, `DELETE` 请求时,不能作为第三方链接的 Cookie
为了更好的防御CSRF攻击,我们可以组合使用以上防御手段。
CSRF的本质
CSRF为什么能够攻击成功?其本质原因是重要操作的所有参数都是可以被攻击者猜测到的。攻击者只有预测出URL的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。出于这个原因,可以想到一个解决方案:把参数加密,或者使用一些随机数,从而让攻击者无法猜测到参数值。这是“不可预测性原则”的一种应用。
四、点击劫持
点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在该网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。
典型点击劫持攻击流程
- 攻击者构建了一个非常有吸引力的网页【不知道哪些内容对你们来说有吸引力,我就不写页面了,偷个懒】
- 将被攻击的页面放置在当前页面的 iframe 中
- 使用样式将 iframe 叠加到非常有吸引力内容的上方
- 将iframe设置为100%透明
- 你被诱导点击了网页内容,你以为你点击的是***,而实际上,你成功被攻击了。
点击劫持防御
通常可以写一段JavaScript代码,以禁止iframe的嵌套。这种方法叫framebusting。比如下面这段代码:
- frame busting
if ( top.location != window.location ){
top.location = window.location
}
需要注意的是: HTML5中iframe的 sandbox 属性、IE中iframe的security 属性等,都可以限制iframe页面中的JavaScript脚本执行,从而可以使得 frame busting 失效。
- X-Frame-Options
X-FRAME-OPTIONS是微软提出的一个http头,专门用来防御利用iframe嵌套的点击劫持攻击。并且在IE8、Firefox3.6、Chrome4以上的版本均能很好的支持。
可以设置为以下值:
DENY: 拒绝任何域加载
SAMEORIGIN: 允许同源域下加载
ALLOW-FROM: 可以定义允许frame加载的页面地址
五、HTML5 安全
HTML 5新标签
新标签的XSS
iframe的sandbox
iframe标签一直以来都为人所诟病。挂马、XSS、ClickJacking等攻击中都能看到它不光彩的身影。浏览器厂商也一直在想办法限制iframe执行脚本的权限,比如跨窗口访问会有限制,以及IE中的标签支持security属性限制脚本的执行,都在向着这一目标努力。在HTML 5中,专门为iframe定义了一个新的属性,叫sandbox。使用sandbox这一个属性后,标签加载的内容将被视为一个独立的“源”(源的概念请参考“同源策略”),其中的脚本将被禁止执行,表单被禁止提交,插件被禁止加载,指向其他浏览对象的链接也会被禁止。sandbox属性可以通过参数来支持更精确的控制。
有以下几个值可以选择:
❍ allow-same-origin:允许同源访问;
❍ allow-top-navigation:允许访问顶层窗口;
❍ allow-forms:允许提交表单;
❍ allow-scripts:允许执行脚本。
Link Types: noreferrer
在HTML 5中为a标签和area标签定义了一个新的Link Types:noreferrer。顾名思义,标签指定了noreferrer后,浏览器在请求该标签指定的地址时将不再发送Referer。这种设计是出于保护敏感信息和隐私的考虑。因为通过Referer,可能会泄露一些敏感信息。这个标签需要开发者手动添加到页面的标签中,对于有需求的标签可以选择使用noreferrer。
安全扫描工具
1. Arachni
Arachni是基于Ruby的开源,功能全面,高性能的漏洞扫描框架,Arachni提供简单快捷的扫描方式,只需要输入目标网站的网址即可开始扫描。它可以通过分析在扫描过程中获得的信息,来评估漏洞识别的准确性和避免误判。
Arachni默认集成大量的检测工具,可以实施 代码注入、CSRF、文件包含检测、SQL注入、命令行注入、路径遍历等各种攻击。
同时,它还提供了各种插件,可以实现表单爆破、HTTP爆破、防火墙探测等功能。
针对大型网站,该工具支持会话保持、浏览器集群、快照等功能,帮助用户更好实施渗透测试。
2. Mozilla HTTP Observatory
Mozilla HTTP Observatory,是Mozilla最近发布的一款名为Observatory的网站安全分析工具,意在鼓励开发者和系统管理员增强自己网站的安全配置。用法非常简单:输入网站URL,即可访问并分析网站HTTP标头,随后可针对网站安全性提供数字形式的分数和字母代表的安全级别。
检查的主要范围包括:
- Cookie
- 跨源资源共享(CORS)
- 内容安全策略(CSP)
- HTTP公钥固定(Public Key Pinning)
- HTTP严格安全传输(HSTS)状态
- 是否存在HTTP到HTTPs的自动重定向
- 子资源完整性(Subresource Integrity)
- X-Frame-Options
- X-XSS-Protection
3. w3af
W3af是一个基于Python的Web应用安全扫描器。可帮助开发人员,有助于开发人员和测试人员识别Web应用程序中的漏洞。
扫描器能够识别200多个漏洞,包括跨站点脚本、SQL注入和操作系统命令。
作者:Lafite-R
链接:https://juejin.cn/post/6946135398443646984
文末福利
近几年,随着移动互联网、大数据、云计算、人工智能等新一代信息技术的快速发展,据腾讯安全《2017上半年互联网安全报告》显示,近年我国高校教育培养的信息安全专业人才仅3万余人,而网络安全人才总需求量则超过70万人,缺口高达95%。
为帮助大家学习网络安全,这里分享一份就业级知识架构体系图。
如图片过大被平台压缩导致模糊,可以在文末下载高清无水印版
一些我收集的网络安全自学入门书籍
一些我自己买的、其他平台白嫖不到的视频教程:
以上学习路线附全套教程无偿分享,如有朋友需要扫码下方二维码免费获取,免费领取!