web 安全讲述
确保您的 Web 站点或 Web 应用安全是十分重要的,即使是代码中很小的 bug 也可能导致隐私信息被泄露,黑客会尝试偷窃数据。这些文档提供信息帮助您使代码更安全。此处列出的面向 Web 安全的文章提供的信息可以帮助您保护站点及其代码免受攻击和数据窃取。
- CSP 内容安全策略
- xss 跨站点脚本攻击
- CSRF 跨站点请求伪造
CSP 内容安全策略
CSP 的主要目标是减少和报告 XSS 攻击,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。
CSP 通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除 XSS 攻击所依赖的载体。一个 CSP 兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和 HTML 的事件处理属性)。
Content-Security-Policy: policy
一个网站管理者允许网页应用的用户在他们自己的内容中包含来自任何源的图片, 但是限制音频或视频需从信任的资源提供者(获得),所有脚本必须从特定主机服务器获取可信的代码, 启用发送违规报告,你需要指定 report-uri 策略指令,并提供至少一个 URI 地址去递交报告:
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com; report-uri http://reportcollector.example.com/collector.cgi
xss 跨站点脚本攻击
跨站脚本攻击 Cross-site scripting (XSS,为了不和 CSS 重名)是一种安全漏洞,攻击者利用这种漏洞可以在客户端注入恶意代码,可以完成获取 cookie、session 的读取,还可以利用脚本串改 HTML 内容,引导用户进入第三方恶意站点,主要表现就是:
- 将一些隐私数据像 cookie、session 发送给攻击者,
- 将受害者重定向到一个由攻击者控制的网站,
- 在受害者的机器上进行一些恶意操作。
目前常见的分类包括了:
- 存储型【永久型】:包括了服务端的操作
- 反射型:有服务端的参与
- DOM 型:纯客户端的攻击
存储型【持久型】
主要是表现在客户端的输入内容【博客内容、表单提交、富文本编辑等】提交到服务端,被服务端保存,并在返回到客户端进行展示;如果其中含有恶意脚本<script>alert(‘我是存储型 XSS 攻击 ')</script>
,并被客户端插入到文档流中,那么恶意脚本会被执行,恶意脚本可以完成读取隐私数据、重定向、修改页面展示结构等操作。
反射型【非持久型】
反射型 XSS 只是简单地把用户输入的数据“反射”给浏览器,这种攻击方式往往需要攻击者诱使用户点击一个恶意链接,或者提交一个表单时,恶意链接中的而已脚本参数或者表单提交的恶意脚本经过服务端的关联,注入到了当前访问的文档流中,恶意脚本被执行,和存储型一样,恶意脚本都可以完成读取隐私数据、重定向、修改页面展示结构等操作。
基于 DOM 型
这是一种纯客户端的攻击,客户端在处理页面地址链接时将恶意脚本注入到了正常文档流中,或者是编辑富文本的时候将它处赋值的含有恶意脚本的富文本插入到了文档流中,导致恶意脚本的执行。同样可以完成读取隐私数据、重定向、修改页面展示结构等操作。
防范 xss
- 保证隐私数据的安全性,
添加 cookie 时,设置Secure; HttpOnly
,仅支持 https 连接和脚本无法读取。Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
- 处理任何用户端的输入
用户端的自定义输入是完全无法保证的,所以需要进行处理,包括特殊字符的转译和限制长度等。 - 服务端的数据转译
如果服务端的数据遭到了存储型攻击,那么就需要对服务端的数据进行必要的转译编码,
CSRF 跨站点请求伪造
跨站请求伪造(CSRF)是一种冒充受信任用户,向服务器发送非预期请求的攻击方式。例如,这些非预期请求可能是通过在跳转链接后的 URL 中加入恶意参数来完成:<img src="https://www.example.com/index.php?action=delete&id=123">
对于在 https://www.example.com 有权限的用户,这个 <img> 标签会在他们根本注意不到的情况下对 https://www.example.com 执行这个操作,即使这个标签根本不在 https://www.example.com 内亦可。
解决方法
- 验证 HTTP Referer 字段
- 添加验证码
- 添加 token【服务端 sessiontoken 和 表单页面 token/request-header 自定义头、cookie[token] 和 表单页面 token/request-header 自定义头】