浏览器安全
浏览器安全可分为
- Web 页面安全
- 浏览器网络安全
- 浏览器系统安全
Web 页面安全
同源策略、CSP(Content-Security-Policy) 和 CORS(Cross-Origin Resource Sharing) 之间的关系
- 同源策略是浏览器的一个安全机制,使用 XMLHttpRequest 和 Fetch 都是无法直接进行跨域请求的,
但是页面可以引用第三方资源(如:img,js,css,html),这样就会暴露一些 XSS 攻击的安全。CSP 是浏览器为了解决 XSS 攻击引入的一个安全策略
- CSP 核心思想:让服务器决定浏览器能够加载哪些资源,决定浏览器是否能够执行内联 JavaScript 代码 - XMLHttpRequest 和 fetch 是无法访问不同域的数据的,因此浏览器又引入了 CORS(跨域资源共享)策略,让其可以安全的进行跨域操作
- 服务器配置 Access-Control-Origin-Allow: 允许跨域的域名
同源策略、CSP 和 CORS 之间的关系:
同源策略就是说同源页面随你瞎搞,但是不同源之间想瞎搞只能通过浏览器提供的手段来搞
比如说
- 读取数据和操作 DOM 要用跨文档机制(window.postMessage)
- 跨域请求要用 CORS 机制
- 引用第三方资源要用 CSP
通俗点,同源策略为了防止
跨站脚本(XSS: Cross Site Scripting)攻击
恶意脚本可以做
- 通过
document.cookie窃取 Cookie 信息。做一些登录后的恶意操作。 - 通过
addEventListener监听键盘的输入。例如窃取信用卡账号和密码并发送到黑客服务器。 - 通过
修改 DOM伪造登录窗口,欺骗用户名和密码等信息。 - 嵌入浮窗广告。
分类
存储型 XSS 攻击(涉及服务器)
攻击步骤
- 将恶意代码提交到服务器数据库中存储(例如通过表单输入脚本代码)
- 页面请求第一步提交的数据,数据库返回恶意代码
- 用户浏览此页面时,恶意代码会运行(将用户的 Cookie 信息等数据上传到攻击者服务器)。
预防
- 对 Cookie 设置 httpOnly ,只允许 http 请求使用,document.cookie 无法获取
- 在前端后端提交数据和保存数据的时候,将数据过滤或转码,脚本的代码会转成普通的字符串
反射型 XSS 攻击(涉及服务器)
Web 服务器接收到请求时,又将恶意代码反射给了浏览器端
- 攻击者通过将恶意代码构造到特殊的 URL中
- 用户点击 URL,服务器将恶意代码从 URL 中取出拼接在 HTML 中返回给浏览器
- 用户解析 HTML 执行,恶意代码被执行
- 恶意代码将用户信息发送到攻击者服务器,或者冒充用户的行为,恶意调用目标网站接口执行攻击者指定的操作
反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。
预防
- 对内容进行过滤或转码
- 利用 CSP(Content-Security-Policy),控制浏览器能够加载哪些资源,决定浏览器只能够执行内联 JavaScript 代码
- 限制加载其他域下的资源文件 eg:
Content-Security-Policy: default-src 'self' - 禁止第三方域提交数据,防止用户数据泄露
- 禁止执行内联脚本和未授权的脚本
- 提供了上报机制,可尽快发现 XSS 攻击
- 限制加载其他域下的资源文件 eg:
- 使用 HttpOnly 属性
基于 DOM 的 XSS 攻击(不涉及服务器)
在 Web 资源传输过程中,修改 HTML 页面(网络劫持)
- 通过 WiFi 路由器劫持
- 通过本地恶意软件劫持
预防 DOM 型 XSS 攻击
- 使用
.innerHTML、.outerHTML、document.write时确保数据可信 - 避免在字符串中拼接不可信数据
实践: 安全检测报告

安全检测工具:https://www.zaproxy.org/
XSS 攻击总结
这三种攻击方式的共同点是都需要往用户的页面中注入恶意脚本,然后再通过恶意脚本将用户数据上传到黑客的恶意服务器上。而三者的不同点在于注入的方式不一样,有通过服务器漏洞来进行注入的,还有在客户端直接注入的。
主要有三种防范策略,第一种是通过服务器对输入的内容进行过滤或者转码,第二种是充分利用好 CSP,第三种是使用 HttpOnly 来保护重要的 Cookie 信息。
转账等安全性要求高的操作,通过添加验证码添加安全性
跨站请求伪造(CSRF: Cross-site request forgery)
什么是 CSRF 攻击
攻击者诱导用户打开第三方网站(攻击者网站),在第三方网站中通过伪造请求登录网站,从而利用用户的登录状态发起跨站请求,做一些恶意行为。
为什么从登录的网站打开第三方网站,第三方可以使用到登录网站的登录状态?
- 没设置 SameSite 情况下,登录站点A.com后(此时有登录状态)
- 诱导跳转到站点B,站点B中做了一些向A.com站点请求的伪造请求(img 或 form的请求,这些请求不受跨域限制):A.com/act=xxx。此时浏览器会默认携带 A.com 的登录状态(Cookie) (浏览器处理cookie的机制,做某个域的请求,自动会把这个域的cookie带上)
GET 类型的 CSRF
在攻击者页面的 HTML 代码中,将恶意请求隐藏在 img 标签内,当页面加载时,自动发起 Get 请求
POST 类型的 CSRF
在攻击者页面的 HTML 代码中,将恶意请求伪造在 form 标签中,用脚本提交 document.getElementById('form').submit()
诱导用户点击链接类型的 CSRF
在攻击者页面中,防止一个诱导 A 标签,实际 href 是攻击操作。需要用户点击链接才会触发
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
重磅消息!!
<a/>
预防
CSRF 的特点
- CSRF (通常)发生在第三方域名
- CSRF 攻击者不能窃取到 Cookie 信息,只是使用
针对 CSRF 的特点,指定防护策略:
- 阻止不明外域访问
- 同源检测
- Samesite Cookie
- 提交时要求附加本域才能获取到的信息
- CSRF Token
- 双重 Cookie 验证
具体策略
- 利用 Cookie 的 SameSite 属性
SameSite=Strict浏览器完全禁止第三方Cookie如果你从极客时间的页面中访问 InfoQ 的资源 ,而 InfoQ 的某些 Cookie 设置了 SameSite = Strict 的话, 那么这些 Cookie 是不会被发送到 InfoQ 的服务器上的。 只有你从 InfoQ 的站点去请求 InfoQ 的资源时,才会带上这些 Cookie。
SameSite=Lax在跨站点的情况下,从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但如果在第三方站点中使用 Post 方法,或者通过 img、iframe 等标签加载的 URL,这些场景都不会携带 Cookie。
SameSite=none在任意情况都会发送 Cookie 数据
eg: Set-Cookie: key=value; SameSite=None; Secure
- 服务器验证请求的来源站点
Referer 是 HTTP 请求头中的一个字段,记录了该 HTTP 请求的来源地址

Origin 属性只包含了域名信息,并没有包含具体的 URL 路径,这是 Origin 和 Referer 的一个主要区别 Origin 的值之所以不包含详细路径信息,是有些站点因为安全考虑,不想把源站点的详细路径暴露给服务器。
服务器的策略是优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值
- CSRF Token
- 浏览器向服务器发起请求,服务器返回一个 CSRF Token,植入到页面中
- 浏览器如果要发起类似“转账”类的请求,需要携带 CSRF Token,服务器验证 Token 是否合法。

Web 网页安全总结
Web 安全问题主要原因是浏览器为同源策略开的两个后门
- 页面中可以任意引用第三方资源
- 通过 CORS 策略让 XMLHttpRequest 和 Fetch 去跨域请求资源
为了解决这些问题
- 引入了
CSP来限制页面任意引入外部资源 - 引入了
HttpOnly机制来禁止JavaScript通过document.cookies的读取 - 引入了
SameSite和Origin来防止CSRF攻击
浏览器系统安全
参考文章: