前端必须懂的计算机网络知识—(XSS、CSRF和HTTPS)

xiaoxiao2025-06-04  68

前端必须懂的计算机网络知识系列文章:

DNS服务器和跨域问题计算机网络的分层模型IP地址和MAC地址前端必须懂的计算机网络知识—(跨域、代理、本地存储)前端必须懂的计算机网络知识—(TCP)前端必须懂的计算机网络知识—(HTTP)前端必须懂的计算机网络知识—(XSS、CSRF和HTTPS)

HTTP为什么不安全

可能被窃听: HTTP 本身不具备加密的功能,HTTP 报文使用明文方式发送由于互联网是由联通世界各个地方的网络设施组成,所有发送和接收经过某些设备的数据都可能被截获或窥视。(例如大家都熟悉的抓包工具:Wireshark),即使经过加密处理,也会被窥视是通信内容,只是可能很难或者无法破解出报文的信息而已 认证问题 无法确认你发送到的服务器就是真正的目标服务器(可能服务器是伪装的)无法确定返回的客户端是否是按照真实意图接收的客户端(可能是伪装的客户端)无法确定正在通信的对方是否具备访问权限,Web服务器上某些重要的信息,只想发给特定用户即使是无意义的请求也会照单全收。无法阻止海量请求下的 DoS 攻击(Denial of Service,拒绝服务攻击)。 可能被篡改 请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击被称为中间人攻击(Man-in-the-Middle attack,MITM)。

XSS攻击

XSS,即为(Cross Site Scripting),中文名为跨站脚本,跨站脚本的重点不在“跨站”上,而在于“脚本”上。大多数XSS攻击的主要方式是嵌入一段远程或者第三方域上的JS代码,实际上是在目标网站的作用域下执行了这段第三方域上的js代码。

反射型XSS(非持久型XSS)

特点:就像镜子反射一样,浏览器发射含XSS的url,服务器将其反射回来

浏览器发生请求时,XSS代码出现在请求URL中,作为参数提交到服务器,服务器解析并响应,响应结果中包含XSS代码,最后浏览器解析并执行。

案例:表单提交

//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标签:

<figure>[图片上传中...(image-f8c94b-1540438754800-6)]

<figcaption></figcaption>

</figure>

点击<测试>按钮,一个XSS攻击就发生了。下面图片中是获取了本地的部分cookie信息:

<figure>[图片上传中...(image-67f5f4-1540438754800-5)]

<figcaption></figcaption>

</figure>

上面只是模拟攻击,通过alert获取到了个人的cookie信息。一般黑客会注入一段第三方的js代码,然后将获取到的cookie信息存到他们的服务器上,拿到我们的身份认证做一些违法的事情了。

存储型XSS(持久型XSS)

特点:黑客将XSS代码发送给服务器,然后通过服务器散播

黑客将XSS代码发送到服务器(不管是数据库、内存还是文件系统等。)其他人请求页面的时候就会带上XSS代码了。

案例:最典型的就是留言板XSS。

黑客提交了一条包含XSS代码的留言到数据库。当目标用户查询留言时,那些留言的内容会从服务器解析之后加载出来。浏览器发现有XSS代码,就当做正常的HTML和JS解析执行。XSS攻击就发生了。

DOM型XSS

特点:DOM XSS代码不需要服务器端的解析响应的直接参与,而是完全通过浏览器端的DOM解析。

浏览器的代码中含有eval,new Function等将字符串内容执行的代码在执行的字符串中嵌入可以执行XSS代码字符串 案例: test.addEventListener('click', function () { var node = window.eval(txt.value) window.alert(node) }, false) //txt中的代码如下: <img src='null' onerror='alert(123)' /> 复制代码

XSS危害

通过document.cookie盗取cookie使用js或css破坏页面正常的结构与样式流量劫持(通过访问某段具有window.location.href定位到其他页面)Dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户无法得到服务器响应。利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。

XSS防御

XSS攻击可以看出,不能原样的将用户输入的数据直接存到服务器,需要对数据进行一些处理:

过滤危险的DOM节点。如具有执行脚本能力的script, 具有显示广告和色情图片的img, 具有改变样式的link, style, 具有内嵌页面的iframe, frame等元素节点。过滤危险的属性节点。如on-, style, src, href等对cookie设置httpOnly,但是也会导致前台无法操作cookie,不太推荐。

CSRF

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,攻击者盗用了你的身份,以你的名义发送恶意请求。

<figure>[图片上传中...(image-1010c6-1540438754800-4)]

<figcaption></figcaption>

</figure>

特点:

登录受信任网站A,并在本地生成Cookie。在不登出受信任网站A的情况下,访问危险网站B。危险网站会向受信任A的网站发送请求,同时会携带受信任网站A本地生成Cookie(用同一个浏览器访问同一个域的接口)

案例:

//钓鱼网站,利用用户的cookie进行权限操作转账 <body onload="steal()"> <iframe name="steal" display="none"> &emsp;&emsp; <form method="POST"name="transfer"&emsp;action="http://www.myBank.com/Transfer.php"> &emsp;&emsp;&emsp;&emsp; <input type="hidden" name="toBankId" value="11"> &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<input type="hidden" name="money" value="1000"> &emsp;&emsp;&emsp;&emsp;</form> &emsp;&emsp;</iframe> </body> 复制代码

CSRF的危害

篡改目标网站上的用户数据;盗取用户隐私数据;作为其他攻击向量的辅助攻击手法;传播CSRF蠕虫。

CSRF的防御

验证码,因为验证码必须在受信任的网站上发送给浏览器的,并且伪造的网站和受信任的网站非同源,所以没有办法获取受信任网站发送的session,所以验证码是没有办法伪造的。refer,标识了当前请求的页面的源,伪造网站可以篡改成受信任的网站源,并不保险token,由于它是通过服务的发送给客户端的令牌,并且存储在浏览器的localstorage中,由于同源策略,并且token还有校验规则,所以token并不能轻易篡改。

Token和JWT

Token的特点

session是通过cookie传输的,每次访问网站都会自主的带上,所以存在安全问题和浪费带宽,token存储在localstorage,可以选择性发送给后台,由于同源策略,安全性高session在集群服务器中很难实现共享,服务器必须存在一份sessionq清单,token不需要存储清单,共用一个密钥,发送token可以实现共享session销毁后会从清单消失,token的注销不好实现,没有清单证明这个token不能用,所以得用一个黑名单来标注

JWT

jwt是实现token的一种方式,一个token分3部分,3部分之间用“.”号做分隔:

header:头部为base64字符串payload:载荷为base64字符串signature:签证 hader+payload经过key加密得出

EXP:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT原理: 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; 复制代码 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); 复制代码 JWT前台 //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> 复制代码

HTTPS(HTTP+TLS/SSL)

TLS/SSL

TLS/SSL的功能实现主要依赖于三类基本算法:

非对称加密实现身份认证和密钥协商

对称加密算法采用协商的密钥对数据加密

散列函数验证信息的完整性,针对于密钥泄露的不安全性

<figure>[图片上传中...(image-cd5446-1540438754799-1)]

<figcaption></figcaption>

</figure>

结合三类算法的特点,TLS 的基本工作方式:

客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取

对称加密

相同的密钥可以用于信息的加密和解密,掌握密钥才能获取信息,能够防止信息窃听,通信方式是1对1(前提示密钥不泄露)算法公开、计算量小、加密速度快、加密效率高客户端、服务器双方都需要维护大量的密钥,维护成本很高因每个客户端、服务器的安全级别不同,密钥容易泄露,交易双方都使用同样钥匙,安全性得不到保证

非对称加密

非对称加密算法的特点加密和解密分别使用不同的密钥,客户端用公钥对请求内容加密,服务器使用私钥对内容解密,反之亦然。相对来说加解密速度较慢,使用非对称加密在数据加密解密过程需要消耗一定时间,降低了数据传输效率公钥是公开的,所以针对私钥加密的信息,黑客截获后可以使用公钥进行解密,获取其中的内容公钥并不包含服务器的信息,使用非对称加密算法无法确保服务器身份的合法性,存在中间人攻击的风险,服务器发送给客户端的公钥可能在传送过程中被中间人截获并篡改

完整性验证算法

常见的有 MD5、SHA1、SHA256,该类函数特点是函数单向不可逆、对输入非常敏感、输出长度固定,针对数据的任何修改都会改变散列函数的结果,用于防止信息篡改并验证数据的完整性在信息传输过程中,散列函数不能单独实现信息防篡改,因为明文传输,中间人可以修改信息之后重新计算信息摘要,因此需要对传输的信息以及信息摘要进行加密

密钥协商

<figure>[图片上传中...(image-88286d-1540438754799-3)]

<figcaption></figcaption>

</figure>

<figure>[图片上传中...(image-f99f09-1540438754799-2)]

<figcaption></figcaption>

</figure>

身份验证

由于非对称加密无法确保服务器身份的合法性,存在中间人攻击的风险,例如:

客户端 C 和服务器 S 进行通信,中间节点 M 截获了二者的通信

节点 M 自己计算产生一对公钥pub_M和私钥 pri_M

C 向 S 请求公钥时,M 把自己的公钥pub_M发给了 C

C 使用公钥pub_M加密的数据能够被M解密,因为M掌握对应的私钥pri_M,而C无法根据公钥信息判断服务器的身份,从而 C 和 M 之间建立了“可信”加密连接

中间节点 M 和服务器S之间再建立合法的连接,因此 C 和 S 之间通信被M完全掌握,M 可以进行信息的窃听、篡改等操作。

<figure>[图片上传中...(image-512949-1540438754799-0)]

<figcaption></figcaption>

</figure>

服务方 Server 向第三方机构CA提交公钥、组织信息、个人信息(域名)等信息并申请认证;CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;如信息审核通过,CA会向申请者签发认证文件-证书。证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名; 签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用CA的私钥对信息摘要进行加密,密文即签名;客户端 Client 向服务器 Server 发出请求时,Server 返回证书文件;客户端 Client 读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即公钥合法;客户端还会验证证书相关的域名信息、有效时间等信息;客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应 CA的证书,证书也会被判定非法。客户端的证书从生产出来之后就内置在主机中

搭建一个HTTPS服务器

搭建一个HTTPS服务器

结语

前端必须懂的计算机网络知识系列已经全部结束,欢迎大家研究讨论!

作者:梦想攻城狮 链接:https://juejin.im/post/5bb2d1c1e51d450e5162a865 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载请注明原文地址: https://www.6miu.com/read-5031271.html

最新回复(0)