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.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的功能实现主要依赖于三类基本算法:
因为非对称加密没法确保服务器身份的合法性,存在中间人攻击的风险,例如:
前端必须懂的计算机网络知识系列已经所有结束,欢迎你们研究讨论!