网络安全防范
iframe
- 如何让自己的网站不被其他网站的iframe引用
// 检测当前网站是否被第三方iframe引用
// 若相等证明没有被第三方引用,若不等证明被第三方引用。当发现被引用时强制跳转百度。
if(top.location != self.location){
top.location.href = 'http://www.baidu.com'
}
- 如何禁用,被使用的iframe对当前网站进行某些操作
- 使用HTML5新增的标签属性sandbox,多值使用空格隔开。
- allow-same-origin:允许被视为同源,即可操作父级DOM或cookie等
- allow-top-navigation:允许当前iframe的引用网页通过url跳转链接或加载
- allow-forms:允许表单提交
- allow-scripts:允许执行脚本文件
- allow-popups:允许浏览器打开新窗口进行跳转
- "":设置为空时上面所有允许全部禁止
- 使用HTML5新增的标签属性sandbox,多值使用空格隔开。
opener
- 项目中打开新标签一般会用到两种方式:
- 使用a标签
- 使用
window.open('xxx')
- 当跳转的网页具有恶意代码时,会将原网页导航到新的网址。
- 恶意网站可以伪造一个足以欺骗用户的页面,使得进行恶意破坏。
window.opener.location.replace('https://www.baidu.com'); //测试无效??
XSS(跨站脚本攻击)
将可执行的代码注入到网页。通常都会:将 cookies 或其他隐私信息发送给攻击者,将受害者重定向到由攻击者控制的网页,或是经由恶意网站在受害者的机器上进行其他恶意操作。
攻击类型
- 存储型
- 将代码写入数据库
- 危害性大
- 反射型
- 通过修改
URL
参数的方式加入攻击代码,诱导用户访问链接进行攻击 - 如:
http://www.domain.com?name=<script>alert(1)</script>
- 通过修改
- DOM型
- 修改原始的客户端代码,受害者浏览器的DOM环境改变
防范方式
- 转义字符,将
引号
、尖括号
、斜杠
进行转义
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
对于富文本来说,使用白名单的过滤方法
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
console.log(html)
使用 js-xss
来实现,可以看到在输出中保留了 h1
标签且过滤了 script
标签。
- 对于vue或react,避免使用
v-html
/dangerouslySetInnerHTML
- 对输入进行验证:比如一些常见的数字、URL、电话号码、邮箱地址等等做校验判断
- 开启浏览器XSS防御:HttpOnly cookie,禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- CSP建立白名单,告诉浏览器哪些外部资源可以加载和运行,配置好规则,减少XSS攻击。兼容性不错。
- 开启CSP的方法
- 设置
HTTP Header
中的Content-Security-Policy
default-src 'self'
只允许本站资源img-src https://*
只允许加载HTTPS协议图片child-src 'none'
允许加载任何来源框架- 更多请查看文档
- 设置
<meta>
标签的方式<meta http-equiv="Content-Security-Policy" >
- 设置
- 开启CSP的方法
CSRF(跨站请求伪造)
CSRF 攻击思想:(核心2和3)
- 浏览并登录信任网站(举例:淘宝)
- 登录成功后在浏览器产生信息存储(举例:cookie)
- 用户在没有登出淘宝的情况下,访问危险网站
- 危险网站中存在恶意代码,代码为发送一个恶意请求(举例:购买商品/余额转账)
- 携带刚刚在浏览器产生的信息进行恶意请求
- 淘宝验证请求为合法请求(区分不出是否是该用户发送)
- 达到了恶意目标
防范 CSRF 攻击可以遵循以下几种规则:
- 涉及到数据修改操作严格使用 post 请求而不是 get 请求
- 阻止第三方网站请求接口
- 请求时附带验证信息比如
验证码
或者Token
- HTTP头自定义属性验证
- 对Cookie设置SameSite
- 该属性表示Cookie不随跨域请求发送
- 可以很大程度减少
CSRF
的攻击,但该属性目前并不是所以浏览器都支持
- 验证
Referer
- 通过验证来判断请求是否为第三方网站发起的
origin、host、referer的区别 1.host:指明了请求服务器的域名/IP地址和端口号。主要应用在虚拟主机技术上,利用虚拟技术把一台完整的服务器分成若干个主机,因此可以在单一主机上运行多个网站或服务。
2.referer:包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。包括协议+域名+端口号+路径+参数(注意,不包含 hash值)。服务端一般使用 Referer 首部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等,还有个常见的用途是图片防盗链。
3.origin:指示了请求来自于哪个站点。该字段仅指示服务器名称,并不包含任何路径信息。主要用于 CORS: 当我们的浏览器发出跨站请求时,服务器会校验当前请求是不是来自被允许的站点。服务器就是通过 Origin 字段的值来进行判断。
点击劫持
攻击者将需要攻击的网站通过iframe
嵌套在自己的网页中,并且将iframe
设置为透明,在页面中透出一个按钮诱导用户点击。
防御方法:
- 设置
X-FRAME_OPTIONS
,这个HTTP响应头就是为了防御iframe嵌套的点击劫持攻击DENY
表示页面不允许用过iframe的方式展示SAMEORIGIN
表示页面可以在相同域名下通过iframe的方式展示ALLOW_FROM
表示页面可以在指定来源的iframe中展示
- JS防御:不允许被iframe
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
// 如果该网页为普通页面
// self表示自身窗口的引用,top表示最顶层的浏览器窗口的引用
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>
以上代码表示:当通过iframe的方式加载页面时,攻击者的网页直接显示所有内容。
HSTS
HTTP严格传输。
当页面进行重定向时,302的重定向有可能就会被劫持,篡改层一个恶意或钓鱼网址。
HSTS:通知浏览器此网站禁止使用HTTP方式加载,浏览器应该自动把所有尝试使用HTTP的请求替换为HTTPS请求。
用户首次访问时并不受HSTS保护,我们可以通过 浏览器预置HSTS域名列表 或 将HSTS信息加入到域名系统记录中,来解决第一次访问的问题。
CDN劫持
处于性能考虑,我们可能会把静态资源放在CDN中,如果CDN服务器被劫持,那么攻击者就可以肆意篡改我们的页面,实施攻击。
现在的CDN以支持SRI为荣,script
和link
标签也有了新的属性integrity
,这个属性是为了判断资源完整性来判断是否被篡改。它通过验证获取文件的哈希值是否和提供的哈希值一致来判断。
integrity
属性分为两个部分,第一部分是指定哈希值的生成算法,第二部分是经过编码实际的哈希值,中间通过-
来连接。
使用SRI需要两个条件:
- 要保证资源同域或者开启跨域
- 提供签名以供校验
中间人攻击
中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。
验证证书的有效性,就是为了检测中间人攻击
通常来说不建议使用公共的 Wi-Fi
,因为很可能就会发生中间人攻击的情况。如果你在通信的过程中涉及到了某些敏感信息,就完全暴露给攻击方了。
当然防御中间人攻击其实并不难,只需要增加一个安全通道来传输信息。HTTPS 就可以用来防御中间人攻击
,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP
从而实现中间人攻击。