XSS 防护
输入输出过滤
- xss.js - HTML 转义
encodeURI
orencodeURIComponent
- url 地址转义
Cookie 设置 HttpOnly
Cookie 设置 HttpOnly 禁止通过 JS 方式读取 Cookie。
Content-Security-Policy 内容安全策略
CSP(Content-Security-Policy) 本质上是开发者可以自定义的白名单制度,可以告诉浏览器可以加载和执行哪些外部资源。
有两种方式可以启用 CSP:
- 设置 HTTP 响应头
Content-Security-Policy
- 设置网页的
<meta>
标签
CSRF 防护
**建议:**客户端发送请求携带 token,服务端校验 token 有效性(如用户登录凭证)
其他补充方式:
- 服务端校验请求头 referer 是否是安全的来源。缺点:一些插件可以伪造
- 不开启 CORS,禁止跨域请求。缺点:可通过反向代理和
<img>
<script>
等方式解决 - 敏感操作使用验证码。缺点:用户体验不友好
点击劫持
点击劫持主要是通过 iframe 或 图片遮挡(例如发布带有恶意图片地址的文章)的方式诱导用户进入自己的页面,并与页面进行交互。
解决方案:
- 设置 X-Frame-Options 响应头,限制其他站点通过 iframe 方式嵌入网页。
- 做好 XSS 和 CSRF 防护,避免攻击者向网站注入恶意代码
中间人攻击
中间人攻击主要指攻击者拦截通信两端的通话,并插入新的内容。
解决方案:使用 HTTPS 通信协议。
window.open
DOM API
默认,通过 window.open() 开启的窗口和调用方法的窗口可以通过 DOM API 互相访问上下文(如果满足同源策略,则还能互相访问对方的属性和方法):
// http://a.example.com
const newWindow = window.open('http://b.example.com')
console.log(newWindow.opener === window) // true
// http://b.example.com
console.log(window.opener)
建议打开不信任的外部页面时指定 noopener
:
window.open('http://b.example.com', '_blank', 'noopener=yes')
默认打开窗口请求的页面会携带 Referer
请求头,如 Referer: http://a.example.com
。
可以指定 noreferrer
省略这个请求头,并且它还会设置 noopener
:
window.open('http://b.example.com', '_blank', 'noreferrer=yes')
Cross Origin Opener Policy 响应头
COOP(Cross-Origin-Opener-Policy),跨源开放者策略。
默认情况下,在页面中调用 window.open(<页面地址>)
打开,COOP 用来限制 window.open()
方式打开的窗口是否可以访问 opener
。
COOP 有三个值:
unsafe-none
same-origin-allow-popups
same-origin
**示例:**假设有三个页面,在 A 页面调用 window.open()
分别打开 B 和 C(没有指定 noopener
和 noreferrer
),三个页面地址分别是:
- A 页面:
http://127.0.0.1:3000
(打开窗口方) - B 页面:
http://127.0.0.1:5000
(被打开窗口方,与 A 不同源) - C 页面:
http://127.0.0.1:3000
(被打开窗口,与 A 同源)
不论 A 页面的 COOP 为何值,A 都能获取并访问 B 和 C 的上下文引用(window
对象),而 B 和 C 页面访问 window.opener
的值有以下几种情况:
A unsafe-none |
A same-origin-allow-popups |
A same-origin |
|
---|---|---|---|
B unsafe-none |
A 窗口的 window 对象 |
A 窗口的 window 对象 |
null |
B same-origin-allow-popups |
null |
null |
null |
B same-origin |
null |
null |
null |
C unsafe-none |
A 窗口的 window 对象 |
A 窗口的 window 对象 |
null |
C same-origin-allow-popups |
null |
A 窗口的 window 对象 |
null |
C same-origin |
null |
null |
A 窗口的 window 对象 |
规律总结为:
unsafe-none
的 A 只允许同样设置了unsafe-none
的窗口访问自己,不论是否同源same-origin-allow-popups
的 A 只允许设置了unsafe-none
的窗口,和设置了同样same-origin-allow-popups
且同源的窗口访问自己same-origin
的 A 只允许设置了同样same-origin
且同源的窗口访问自己
COOP 只是预防打开的窗口反向获取 opener
,这相当于从服务端屏蔽了不信任的站点,相比于在调用 window.open()
时保证指定 noopener
或 noreferrer
,COOP 更方便和有保障。
但是,COOP 仅基于三种值和同源策略提供了几种配置场景,要想在其他场景限制 open 窗口的互相访问上下文,还是要在 window.open()
方法中指定 noopener
。
最后,建议配置响应头 Cross-Origin-Opener-Policy
为 same-origin
。