常见的web前端攻击方式有哪些
XSS
Cross Site Script
跨站脚本攻击- 手段:黑客将JS代码插入到网页内容中,渲染时执行
JS
代码 - 预防:特殊字符串替换(前端或后端)
CSRF
Cross Site Request Forgery
跨站请求伪造- 手段:黑盒诱导用户去访问另一个网站的接口,伪造请求
- 预防:严格的跨域限制 + 验证码机制
- 判断
referer
- 为
cookie
设置sameSite
属性,禁止第三方网页跨域的请求能携带上cookie
- 使用
token
- 关键接口使用短信验证码
- 判断
注意:偷取
cookie
是XSS
做的事,CSRF
的作用是借用cookie
,并不能获取cookie
CSRF攻击攻击原理及过程如下:
- 用户登录了
A
网站,有了cookie
- 黑盒诱导用户到
B
网站,并发起A
网站的请求 A
网站的API
发现有cookie
,会在请求中携带A
网站的cookie
,认为是用户自己操作的
点击劫持
- 手段:诱导界面上设置透明的
iframe
,诱导用户点击 - 预防:让
iframe
不能跨域加载
DDOS
Distribute denial-of-service
分布式拒绝服务- 手段:分布式的大规模的流量访问,使服务器瘫痪
- 预防:软件层不好做,需硬件预防(如阿里云的
WAF
购买高防)
SQL注入
- 手段:黑客提交内容时,写入
sql
语句,破坏数据库 - 预防:处理内容的输入,替换特殊字符
跨域方案
JSONP
利用
<script>
标签没有跨域限制的漏洞。通过<script>
标签指向一个需要访问的地址并提供一个回调函数来接收数据
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script>
- 在开发中可能会遇到多个
JSONP
请求的回调函数名是相同的,这时候就需要自己封装一个JSONP
,以下是简单实现
function jsonp(url, jsonpCallback, success) {let script = document.createElement("script");script.src = url;script.async = true;script.type = "text/javascript";window[jsonpCallback] = function(data) {success && success(data);};document.body.appendChild(script);
}
jsonp("http://xxx","callback",function(value) {console.log(value);}
);
CORS跨域资源共享
方案依赖服务端/后端在响应头中添加
Access-Control-Allow-*
头,告知浏览器端通过此请求。只要后端实现了CORS
,就实现了跨域
CORS
将请求分为简单请求(Simple Requests)和需预检请求(Preflighted requests)
-
简单请求:不会触发预检请求的称为简单请求。当请求满足以下条件时就是一个简单请求:
-
请求方法:
GET
、HEAD
、POST
。 -
请求头:
Accept\Accept-Language
、Content-Language
、Content-Type
Content-Type
仅支持:application/x-www-form-urlencoded
、multipart/form-data
、text/plain
-
-
需预检请求:当一个请求不满足以上简单请求的条件时,浏览器会自动向服务端发送一个
OPTIONS
请求,通过服务端返回的Access-Control-Allow-*
判定请求是否被允许
CORS
引入了以下几个以 Access-Control-Allow-*
开头:
Access-Control-Allow-Origin
表示允许的来源Access-Control-Allow-Methods
表示允许的请求方法Access-Control-Allow-Headers
表示允许的请求头Access-Control-Allow-Credentials
表示允许携带认证信息
nginx反向代理
nginx 配置跨域,可以为全局配置和单个代理配置(两者不能同时配置)
-
全局配置,在
nginx.conf
文件中的http
节点加入跨域信息 -
局部配置(单个代理配置跨域), 在路径匹配符中加入跨域信息
Node 中间层接口转发
Proxy
如果是通过vue-cli
脚手架工具搭建项目,我们可以通过webpack
为我们起一个本地服务器作为请求的代理对象
通过该服务器转发请求至目标服务器,得到结果再转发给前端,但是最终发布上线时如果web应用和接口服务器不在一起仍会跨域
在vue.config.js
文件,新增以下代码
module.exports = {devServer: {host: '127.0.0.1',port: 8080,open: true,// vue项目启动时自动打开浏览器proxy: {'/api': { // '/api'是代理标识,用于告诉node,url前面是/api的就是使用代理的target: "http://xxx.xxx.xx.xx:8080", //目标地址,一般是指后台服务器地址changeOrigin: true, //是否跨域pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'用""代替'^/api': "" }}}}
}
通过axios
发送请求中,配置请求的根路径
axios.defaults.baseURL = '/api'