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的功能實現主要依賴於三類基本算法:
因爲非對稱加密沒法確保服務器身份的合法性,存在中間人攻擊的風險,例如:
前端必須懂的計算機網絡知識系列已經所有結束,歡迎你們研究討論!