1. xss (Cross Site Scripting)
跨站脚本攻击:发生在目标网站中目标用户的浏览器上,当用户浏览器渲染整个HTML文档的过程中执行了不在预期内的脚本时,就发生了xss。
跨站脚本的重点不在‘跨站’上,而在于‘脚本’上。大多数XSS攻击的主要方式是嵌入一段远程或者第三方域上的JS代码。实际上是在目标网站的作用域下执行了这段js代码。
类型
-
反射型xss(非持久型XSS):是指发生请求时,XSS代码出现在请求URL中,作为参数提交到服务器,服务器解析并响应。响应结果中包含XSS代码,最后浏览器解析并执行。
// Front <body> <textarea name="txt" id="txt" cols="80" rows="10"></textarea> <button type="button" id="test">测试</button> <script> let test = document.querySelector('#test') let txt = document.querySelector('#txt') test.addEventListener('click', function () { let url = `test?test=${txt.value}` // 1. 发送一个GET请求 let xhr = new XMLHttpRequest() xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { document.body.insertAdjacentHTML('beforeend', JSON.parse(xhr.responseText).test) } else { console.log('error', xhr.responseText) } } } xhr.open('GET', `http://127.0.0.1:3000/${url}`, true) xhr.send() }) </script> </body> // backend const express = require('express') const app = express() app.use(function (req, res, next) { const {origin} = req.headers res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE') next() }) app.get('/test',(req,res) => { const {test} = req.query console.log(req.query) res.json({ test }) }) app.listen(3000,() => { console.log('app running at port 3000 ...') })
-
存储型 xss
与反射型的差别在于:提交的xss代码会存储在服务器,下次再请求页面的时候不用再提交xss代码
典型案例: 留言板
用户提交一条包含xss代码的留言存储到数据库中,目标用户查看留言板的时候,留言板的内容会从数据库查询出来并显示,浏览器检测到xss代码,会当做正常的html和js执行。
存储型xss是最隐蔽的
-
DOM xss
DOM XSS代码不需要服务器端的解析响应的直接参与,而是通过浏览器端的DOM解析。这完全是客户端的事情。
<script> let test = document.querySelector('#test') let txt = document.querySelector('#txt') test.addEventListener('click', () => { window.eval(txt.value) }) </script>
御防
- 服务端设置httpOnly,禁止浏览器访问cookie
- 对输入(和URL参数)进行过滤,对输出进行编码。即对提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。虽然对输入过滤可以被绕过,但是也还是会拦截很大一部分的XSS攻击。
function htmlEncode(str) { return String(str) .replace(/&/g,'&') .replace(/"/g,'"') .replace(/'/g,''') .replace(/</g,'<') .replace(/>/g,'>') .replace(/`/g, '`') .replace(/\//g, '/') }
2.csrf(Cross—Site Request Forgery)
跨站请求伪造
两个关键点: 跨站点的请求、请求是伪造的
原理:
-
首先用户 A 请求登陆了服务器 B,这时服务器 B 响应了用户 A,并且会返回唯一标识的该用户的 cookie 信息。
-
用户 A 在未退出服务器 B 时(即仍与服务器 B 保持会话状态),又访问了带有恶意脚本的服务器 C,服务器 C 响应给用户 A 一个恶意页面,并且通过恶意脚本伪装用户 A 向服务器 B 发送请求,此时服务器 B 误以为是用户 A 请求,故响应并返回了用户 A 的 cookie 信息。
-
服务器 C 收到用户 A 与 服务器 B 的cookie 信息后,保存起来,并利用该信息伪装成用户 A 去访问服务器 B,再进行相应的破坏
简单点说,CSRF 就是利用用户的登录态发起恶意请求
如何检测csrf漏洞: 抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,证明存在csrf漏洞
御防
-
验证 HTTP Referer 的值
HTTP 的头部 有一个 Referer 信息的字段,如果跳转的网站与来源地址相符,那就是合法的,如果不符则可能是csrf攻击,拒绝该请求
-
添加校验token
- 用户 A 访问服务器 B
- 服务器 B 以某种随机生成策略生成随机字符串,并作为令牌(token)保存在 session 里面,然后夹带着响应返回给用户,并以隐藏域的形式保存在页面中
- 用户每次请求都会夹带着 token 反馈给服务器
- 服务器建立一个拦截器来验证令牌,若令牌验证不通过,则认为该次请求是非法的,拒绝响应。
3.界面操作劫持
- 点击劫持
- 拖拽劫持
- 触屏劫持
实现原理: iframe+透明层
御防
-
X-Frame-Options
取值有 “DENY” 和 “SAMEORIGIN”,分别表示不能使用iframe和只能使用同域的iframe。
-
Frame Busting脚本防御
if(top.location != self.location){ top.location = self.location; }
禁止iframe的嵌套。
csrf与xss最大的区别在于:csrf并没有盗取cookie而是直接利用cookie