导言
记录下最近有关于安全问题的学习,主要从XSS,CSRF,HTTPS,CSP,SRI,页面劫持几个方面来说
XSS
概述
跨域脚本攻击(cross-site scripting)
错误地将用户输入的内容当做了代码的一部分进行执行
场景
防御措施(永远不要相信用户的任何输入)
-
对于后端渲染:
1、HTML标签内容转义
2、内联JavaScript转义
3、URL转义 -
对于前端渲染:
1、使用专业框架规避XSS风险
2、使用.innerHTML/.outerHTML/document.write注意Encode
3、拼接字符串作为代码执行时注意Encode
4、尽量不使用setTimeout(字符串)/new Function/eval
CSRF
概述
跨站请求伪造
攻击者诱导受害者进入第三方网站
在第三方网站中向被攻击网站发送跨站请求
利用受害者在被攻击网站已经获取的登录态,冒充用户对被攻击的网站执行某项操作
攻击原理
场景
防御措施
- 禁止跨站
Samesite Cookie
Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: foo=1; Samesite=Lax
严格模式: 任何情况的跨站请求都不会携带该Cookie
宽松模式: 造成页面刷新且是GET请求才会携带该Cookie
严格模式从新标签进入/打开子域页面都会丢失登录态,用户体验较差
宽松模式安全性较低Samesite不支持子域,且目前兼容性较差
-
防止伪造
使用CSRF Token
服务端输出CSRF Token到页面
页面在发起请求时携带CSRF Token
服务端收到请求时同时校验CSRF Token和登录态 -
隐藏令牌
和Token有点像,比如说放在HTTP的header头中,不放在链接上,这样子会比较隐蔽,本质差不多,只是使用方式有所差别。
页面劫持
概述
其实就是被误导跑到别的地方去了,比如常常在一些电影资源网站点击播放的时候跳到贪玩蓝岳的页面之类的。
劫持场景
防御措施
防止页面被放入iframe
1.使用JS代码判断
判断当前parent是否为top
window.top === window.parent
2.X-Frame-Options 指示浏览器是否允许该页面被放入frame/iframe/embed/object
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from https://example.com/
HTTPS
概述
HTTPS = HTTP + SSL/TLS
- 客户端请求服务端HTTPS端口
- 服务端向客户端发送公钥
- 客户端校验公钥
- 客户端生成随机对称加密秘钥
- 客户端使用公钥加密对称加密秘钥并发送给服务端
- 服务端收到后解密获得对称加密秘钥
- 客户端与服务端使用对称加密秘钥加密消息传输
场景
防御措施
-
HTTP Strict-Transport-Security
使用HTTP访问时强制使用HTTPS 第一次成功HTTPS访问后返回HSTS响应头 以后max-age时间内浏览器均会内部307到HTTPS站点
Strict-Transport-Security: <max-age=>[; includeSubDomains][; preload]
-
HSTS Preload
向谷歌提交HTTPS预加载列表
获取不经过第一次HTTPS的强行调整
CSP
概述
Content Security Policy
内容安全策略
用于检测/阻止/削弱某类攻击
使用HTTP Header/meta进行配置
场景
-
跨站脚本攻击
CSP 的主要目标是减少和报告 XSS 攻击 ,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。
作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行
-
数据包嗅探攻击
除限制可以加载内容的域,服务器还可指明哪种协议允许使用;比如 (从理想化的安全角度来说),服务器可指定所有内容必须通过HTTPS加载。一个完整的数据安全传输策略不仅强制使用HTTPS进行数据传输,也为所有的cookie标记安全标识 cookies with the secure flag,并且提供自动的重定向使得HTTP页面导向HTTPS版本。网站也可以使用 Strict-Transport-Security HTTP头部确保连接它的浏览器只使用加密通道。
使用方法
- 限制文档内加载各类资源的来源域名
- 限制文档内允许提交的表单、访问类型
- 当CSP违规时上报到指定地址
- 指定某些资源使用SRI校验
- 阻止加载和执行外部JS
- 减少XSS和注入劫持
- 防止资源污染
- 统计站点的安全程度
使用示例
Content-Security-Policy: default-src 'self'
Content-Security-Policy: default-src 'self' *.trusted.com
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
SRI
概述
子资源完整性 Subresource Integrity 简称 SRI 是一种安全机制,它用于让浏览器检查所下载的来自第三方的资源(例如 CDN)未被恶意篡改。它使用哈希值检查确保第三方资源的完整性。只要开发者提供了被需下载资源的哈希值,浏览器就可以检查实际下载的文件是否与预期的哈希值匹配。
场景
- CDN劫持
静态资源在CDN被污染/替换/追加额外恶意代码
额外加入的代码可能会导致页面跳转/追加广告/打开APP等
即使是HTTPS也有可能被劫持
CDN劫持通常偶发,难以复现和定位
使用方法
- 只需给 script 或 style 标签添加 integrity 属性即可
- 使用CSP控制SRI的开启
你可以使用 内容安全政策 (CSP)强制要求当前页面所有脚本加载标签启用 SRI。例如
Content-Security-Policy: require-sri-for script;
强制要求所有 script 标签启用 SRI,浏览器会拒绝加载未启用 SRI 的 script 标签。
对应的还有 CSS 版本:
Content-Security-Policy: require-sri-for style;