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攻擊就發生了。下面圖片中是獲取了本地的部分cookie信息: 上面只是模擬攻擊,經過alert獲取到了我的的cookie信息。通常黑客會注入一段第三方的js代碼,而後將獲取到的cookie信息存到他們的服務器上,拿到咱們的身份認證作一些違法的事情了。特色:黑客將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.im/post/5bb1cc2af265da0ae5052496
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的功能實現主要依賴於三類基本算法:
因爲非對稱加密沒法確保服務器身份的合法性,存在中間人攻擊的風險,例如:
前端必須懂的計算機網絡知識系列已經所有結束,歡迎你們研究討論!