一, 基础知识
1,XSS(Cross Site Scripting)跨站脚本攻击
(1)原理: 页面渲染的数据中包含可运行的脚本
(2)攻击的基本类型: 反射型 (url 参数直接注入) 和存储型(存储到 DB 后读取时注入)
(3)注入点: html 节点内的内容(text);HTML 中 DOM 元素的属性; JavaScript 代码; 富文本
- //HTML 节点内容注入
- <div><script>alert(1);</script></div>
- //DOM 属性注入
- <img src='/images/1.png' onerror='alert(1);'>
- //JavaScript 代码
- <script>
- var a = '1';alert(1);''
- </script>
- // 富文本是 HTML 标签, 文字, 以及样式的集合, 很容易实现 HTML 节点内容注入和 DOM 属性注入, 有被攻击的风险
2,CSRF(Cross Site Request Forgy)跨站请求伪造
原理: 在第三方网站向本网站发起请求(如图)
(1)用户在 a 站前端页面发起登录 (身份认证) 请求
(2)a 站后端确认身份, 登录成功, cookie 中存在用户的身份认证信息
(3)b 站前端页面向 a 站后端发起请求, 带着 a 站的 cookie 信息(身份认证信息), 请求成功
综上, 可以清楚的知道, 只要用户访问了 b 站的前端页面, b 站就可以在用户完全不知道的情况下, 带着 a 站的用户登录态 (cookie) 向 a 站发起请求
3, 点击劫持
原理: 第三方网站通过 iframe 内嵌某一个网站, 并且将 iframe 设置为透明不可见, 将其覆盖在其他经过伪装的 DOM 上, 伪装的可点击 DOM(按钮等)与实际内嵌网站的可点击 DOM 位置相同, 当用户点击伪装的 DOM 时, 实际上点击的是 iframe 中内嵌的网页的 DOM 从而触发请求操作
特点: 用户自己做了点击操作; 用户毫不知情;
二, 如何防御
1,XSS 攻击防御
(1)浏览器自带防御机制, 主要应对反射型攻击(HTML 内容或属性):http 响应头中自动添加 x-xss-protection, 值为 0(关闭),1(打开), 默认打开
(2)对特定字符做转义: 内容注入替换尖括号( <=> < > => > ) 属性注入替换单引号或双引号( "=> "' => ' )
(3)CSP(Content Security Policy)内容安全策略: 用于指定哪些内容可执行
- // 我们可以在 http 响应头中设置 Content-Security-Policy
- // 图片可以从任何地方加载(注意 "*" 通配符)
- // 多媒体文件仅允许从 media1.com 和 media2.com 加载(不允许从这些站点的子域名)
- // 可运行脚本仅允许来自于 userscripts.example.com
- Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
- // 同时 meta 中也支持设置 Content-Security-Policy
- <meta http-equiv="Content-Security-Policy" content="default-src'self'; img-src https://*; child-src'none';">
2,CSRF 攻击防御:
CSRF 的发生有几个特点, b 站发送的请求带着 a 站的 cookie 信息; b 站发送请求不经过 a 站的前端; http 请求头中的 referer 为 b 站. 我们可以从这些特点入手, 思考防御的办法
(1)禁止第三方网站携带本网站的 cookie 信息: 设置 same-site 属性, same-site 属性有两个值, Strict(所有的第三方请求都不能携带本网站的 cookie)和 Lax(链接可以, 但是 form 表单提交和 Ajax 请求不行)
(2)本网站前端页面添加验证信息: 使用验证码或者添加 token 验证
验证码: 当发起请求时, 前端需要输入本网站页面的验证码信息, 后端对验证码进行验证, 验证码正确才会进行相关操作(存取数据等)
token 验证: a 站前端将 token 存在当前页面中 (比如表单中的 input 隐藏域, meta 标签或者任何一个 dom 的属性) 和 cookie 中, 当请求 a 站后端的时候, 参数中带上这个 token 字段, a 站后端将参数中的 token 和 cookie 中的 token 做对比, 相同则验证通过, 不同则请求不合法
不管是验证码还是 token 验证, 原理都是一样的, 在 a 站前端页面加入验证, 当第三方网站请求 a 站后端时, 即使能携带 a 站 cookie, 但是因为没有经过 a 站的前端页面从而拿不到验证信息, 也会导致请求失败.
两种防御的方法也有区别, 验证码需要用户去填写, 从而增加了用户使用网站的复杂度, 而 token 验证在用户无感知的情况下就可以实现, 不影响用户体验. 我个人理解, 验证码验证一般使用在需要提高用户认知的场景, 比如, 登录多次失败, 修改个人信息(用户名, 密码, 绑定手机号等等), 而一些获取商品列表信息, 搜索等接口, 使用 token 比较合理. 可以看看我们平时使用的这些网站, 作参考~
(3)referer 验证: 禁止来自第三方的请求
(4)使用 post 请求: 有一个说法是 "post 请求比 get 请求更安全", 那这种说法对不对呢? 实际上这种说法并不准确, 对于 CSRF 攻击来讲, 不管是 post 还是 get 都能实现攻击, 区别只是 post 请求攻击方需要构造一个 form 表单才可以发起请求, 比 get 请求 (img 的 src, a 标签的 href 等等) 的攻击方式复杂了一些, 但是并不能有效的阻止攻击.
3, 点击劫持攻击防御
(1)JavaScript 禁止内嵌: 当网页没有被使用 iframe 内嵌时, top 和 Windows 是相等的; 当网页被内嵌时, top 和 Windows 是不相等的; 可以在本网站的页面中添加如下判断:
- <script>
- if (top.location != Windows.location) {
- // 如果不相等, 说明使用了 iframe, 可进行相关的操作
- }
- </script>
但是这种方式并不是万能的, 因为 iframe 标签中的属性 sandbox 属性是可以禁用内嵌网页的脚本的:
<iframe sandbox='allow-forms' src='...'></iframe>
(2)设置 http 响应头 X-Frame-Options: 有三个值 DENY(禁止内嵌) SAMEORIGIN(只允许同域名页面内嵌) ALLOW-FROM(指定可以内嵌的地址)
能在所有的 web 服务器端预设好 X-Frame-Options 字段值是最理想的状态.
(3)一些辅助手段, 比如添加验证码, 提高用户的防范意识
三, 总结
本文旨在对平时了解到的知识做一些总结和记录, 方便查阅和复习, 描述不当之处, 欢迎指出.
文中有些部分并未深入展开, 比如 iframe 的 sandbox 属性(只适用于内嵌网页是 form 提交的情况, 如果所有的请求都通过 Ajax 来请求, 而 JS 脚本又被禁用的话, 那就没办法实现点击劫持了), 有一些内容需要你自己动脑思考.
后续可能还会有补充, 比如 SQL 注入部分, 总之, 今天先这样啦~
posted on 2019-06-14 10:55 天株 阅读(...) 评论(...) 编辑 收藏
来源: https://www.cnblogs.com/zhiying/p/11018331.html