XSS,即为(Cross Site Scripting),中文名为跨站脚本,跨站脚本的重点不在“跨站”上,而在于“脚本”上。大多数XSS攻击的主要方式是嵌入一段远程或者第三方域上的JS代码,其实是在目标网站的做用域下执行了这段第三方域上的js代码。php
特色:就像镜子反射同样,浏览器发射含XSS的url,服务器将其反射回来css
案例:表单提交html
//test.html <body> <textarea name="txt" id="txt" cols="80" rows="10"> <button type="button" id="test">测试</button> <script> var test = document.querySelector('#test') test.addEventListener('click', function () { var url = `/test?test=${txt.value}` //1.发送一个GET请求 var xhr = new XMLHttpRequest() xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { // 3. 客户端解析JSON,并执行 var str = JSON.parse(xhr.responseText).test var node = `${str}` document.body.insertAdjacentHTML('beforeend', node) } else { console.log('error', xhr.responseText) } } } xhr.open('GET', url, true) xhr.send(null) }, false) </script> </body> 复制代码
//server.js var express = require('express'); var router = express.Router(); router.get('/test', function (req, res, next) { // 2.服务端解析成JSON后响应 res.json({ test: req.query.test }) }) 复制代码
如今咱们经过给textarea添加一段有攻击目的的img标签: 前端
特色:黑客将XSS代码发送给服务器,而后经过服务器散播node
案例:最典型的就是留言板XSS。ios
特色:DOM XSS代码不须要服务器端的解析响应的直接参与,而是彻底经过浏览器端的DOM解析。web
test.addEventListener('click', function () { var node = window.eval(txt.value) window.alert(node) }, false) //txt中的代码以下: <img src='null' onerror='alert(123)' /> 复制代码
XSS攻击能够看出,不能原样的将用户输入的数据直接存到服务器,须要对数据进行一些处理:算法
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,攻击者盗用了你的身份,以你的名义发送恶意请求。 数据库
案例:express
//钓鱼网站,利用用户的cookie进行权限操做转帐 <body onload="steal()"> <iframe name="steal" display="none">    <form method="POST"name="transfer" action="http://www.myBank.com/Transfer.php">      <input type="hidden" name="toBankId" value="11">       <input type="hidden" name="money" value="1000">     </form>   </iframe> </body> 复制代码
jwt是实现token的一种方式,一个token分3部分,3部分之间用“.”号作分隔:
EXP:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
let jwt = { //解码 decode(token,secret){ let [header,content,sign] = token.split('.'); let h = JSON.parse(this.formBase64ToString(header)); let c = JSON.parse(this.formBase64ToString(content)); if(sign !== this.sign([header,content].join('.'),secret){ throw new Error ('Not allowd') } return c }, //加码 encode(payload,secret){ let header = this.toBase64(JSON.stringify({'type':'JWT',alg:'HS25' })); let content = this.toBase64(JSON.stringify(payload)); let sign = this.sign([header,content].join('.'),secret); return [header,content,sign].jion('.'); } //转换为base64 toBase64(str){ return Buffer.from(str).toString('base64'); } //签名 sign(str,secret){ return require('crypto').createHmac('sha256',secret).update(str); } } module.exports = jwt; 复制代码
const express = require('express'); const bodyParser = require('body-parser') const jwt = require('jwt-simple') const userList=[ {id:1,username:'kbz',password:'123456'} ] const SECRET = 'MISS'; let app = express(); app.use(bodyParser.json); //由于请求头中有Authorization字段,这和跨域时要设置name传参数同样,能够参考: //前端必须懂的计算机网络知识—(跨域、代理、本地存储) //https://juejin.cn/post/6844903686775242760 app.use(function(req,res,next){ res.setHeader('Access-Control-Allow-Origin',"*"); res.setHeader('Access-Control-Allow-Headers',"Content-Type,Authorization"); res.setHeader('Access-Control-Allow-Methods',"GET,POST,OPTIONS"); if(req.method === 'OPTIONS'){ res.end(); } next(); }) //登录时发送token app.post('/login',function(req,res,next){ let user = req.body; userList.find(person=>(person.id === user.id)); if(user){ jwt.encode({ id:user.id, username:user.username },SECRET) res.json({ code:0, data:{ token } }) }else{ res.json({ code:1, data:'用户不存在' }) } }) // 须要验证权限,则取token验证 // 请求头Authorization:Bearer token app.get('/order',function(req,res,next){ let authorization = req.headers['authorization']; if(authorization){ let token = authorization.split(' ')[1]; try{ let user = jwt.decode(token,SECRET); req.user = user; }catch(e){ res.status(401).send('Not Allowed') } }else{ res.status(401).send('Not Allowed') } }) app.listen(3000); 复制代码
//login.html <input type="text" id='username' class="form-control"> <input type="text" id='password' class="form-control"> <span onclick='login()'></span> <scrpipt> axios.post('/user').then(res=>{ localStorage.setItem('token',res.data.data.token) location.href='/order' }) </script> //order.html <scrpipt> axios.interceptors.request.use(function(config){ let token = localStorage.getItem('token'); if(token){ config.headers.Authorization = 'Bearer '+ token } }) axios.get('/order').then(res=>{ console.log(res); }) </script> 复制代码
TLS/SSL的功能实现主要依赖于三类基本算法:
因为非对称加密没法确保服务器身份的合法性,存在中间人攻击的风险,例如:
前端必须懂的计算机网络知识系列已经所有结束,欢迎你们研究讨论!