Web开发的安全之旅

94 阅读7分钟

攻击篇

XSS攻击

XSS攻击,即(Cross-Site Scripting),由于和CSS的缩写冲突了,因此改名为XSS。主要利用了对用户提交数据的信任,攻击者才向服务器提交数据的时候,插入恶意脚本代码,从而进行攻击。比如攻击者在提交这个表单的时候,在提交内容中插入以下代码:

<script>alert("XSS")</script>

则加载这条内容的其他用户则会在页面中弹出一个alert

其特点是:

  • 难以从UI上感知
  • 可以窃取用户的cookie或token等信息
  • 可以绘制UI界面,诱骗用户点击或者提交表单信息

总的来说,XSS攻击可以分为以下几类

存储型XSS攻击(Stored XSS)

恶意脚本会被提交到数据库中,当其他用户访问某个页面中的资源时,如视频,恶意代码就会执行,其余过程和上述描述基本一致。危害大,对全部用户可见。

反射型XSS攻击(Reflected XSS)

不涉及到数据库,直接从URL上进行攻击。攻击者在向服务器发送请求的时候,在请求地址后添加一些参数,进行攻击。

http://host:port/params=<script>alert("XSS")</script>

如果服务器直接读取这个地址,并将其得到的params的值直接用于生成DOM片段,则服务器容易受到攻击。当然,对于这个例子,可能不好理解,因为一个alert警示框不会影响服务器。但是如果把<script>alert("XSS")</script>这部分换成可以得到服务端相关数据的代码,或者再次抛出错误,则服务器端容易被窃取数据或造成服务端崩溃。

基于DOM的XSS攻击(DOM-based XSS)

不需要服务器的参与,当浏览器端解析URL路径并使用获得的数据进行DOM的创建和渲染的过程中,容易把恶意代码插入DOM中,造成攻击。与反射型XSS攻击很类似,但是不同的是,基于DOM的攻击不会经过服务器,全部在浏览器端实现。

Mutation-based XSS攻击

利用浏览器渲染DOM的特性进行攻击,在不同浏览器上会有所区别。如:

<noscript><p title="</noscript><img src=x onerror=alert(1)>"></p>

在解析的时候,<noscript><p title="</noscript>会被忽略,而<img src=x onerror=alert(1)>"></p>则会执行,把img放在dom中进行渲染,由于x找不到,则会出发onerror事件,从而执行后面的恶意代码。

CSRF(Cross-site request forgery)跨站请求伪造

在用户不知情的前提下,利用用户权限,如cookie等,构造指定http请求,窃取或修改用户敏感信息。

CSRF-GET

如果用户不小心点击了下面的连接(攻击者有可能已经实现了XSS攻击,在网站上插入了一些攻击者构造的DOM),则会向攻击者指定的地址发送数据,这些数据很有可能是cookies等敏感数据。

<a href="http://host:port/data=someinfo">点我抽奖</a>

或者是其他方式,如利用图片加载时发送的请求

<img src="http://host:port/data=someinfo" style="display: none;">

CSRF-beyond GET

不局限于GET的请求,使用from表单,可以构造任意类型的请求,如:

<form action="post" action="http://host:port">
  <input type="hidden" name="data" value="someinfo">
</form>

注入攻击

SQL注入攻击

攻击者构造恶意SQL参数或语句,在服务器端执行的时候,进行攻击。 假设服务器端在执行查询时,需要接受用户提供的username进行查询

 SELECT * from table where username = ${username}

一旦用户传的usernameany; DROP TABLE table,则会将这个数据集进行删除。当然,可以构造的攻击方法还有很多。

命令注入攻击

如存在一个视频转换的功能,需要用户提供一些参数,如转换配置等

 exec(`convert-cli ${video} -o ${options}`)

一旦用户传的options' && rm -rf xxx,当服务端执行命令的时候,就会把一些服务器上的文件删除。甚至是读取或修改一些私密文件,如linuxi系统上保存密码的/etc/passwd或服务端的一些配置信息等,以及访问服务器上的callback,暴露内网信息。

DoS(Denial os Service)拒绝服务攻击

通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多的请求,导师请求积压,进而导致服务器崩溃。

ReDoS

ReDoS是基于正则表达式的DoS,如果服务器端有一个贪婪模式的正则表达式匹配,攻击者让服务器匹配容易发生大量回溯的特定字符串,从而增加服务器的响应时间,减少服务器的吞吐量。

DDoS(Distributed DoS)分布式拒绝服务攻击

短时间内,攻击者将自己控制的大量僵尸设备向魔偶个特定的服务器集中发送请求,导致服务器崩溃,或者是把服务器带宽耗尽。

典型的DDoS是 SYN DoS,攻击者根据TCP协议的三次握手发送大量的SYN,服务器按照规范返回SYN和ACK,但是此时攻击者不向服务器发送第三次的ACK,服务器就会一直等待,一旦达到最大连接数,服务器就容易崩溃。

中间人攻击

这类攻击容易发生在以下场景中:

  • 数据明文传输
  • 信息篡改不可知
  • 对方身份未验证 说白了就是用户向服务器端发送一些数据的时候,攻击者拦截到用户的请求,进行操作后再返回给服务器,然后拿到服务器的数据,再返回给攻击者想要让用户看到的数据。

防御篇

XSS的防御

不要将用户提交的内容直接转化为DOM,只让其当作字符串。且目前前端主流框架都有默认的防范XSS攻击的配置,或者使用google-closure-library,服务器端使用DOMPurify。如果非要动态生成DOM,则需要:

  • 对用户穿的内容进行转移,如使用DOMParser
  • 对SVG文件进行扫描
  • 最好禁止用户自定义跳转的行为,做好过滤
  • 对用户的自定义样式也要扫描,css中background: url()也会发送网络请求

CSP(Content Security Policy)

CSP能够控制哪些域名是安全的,只执行自定义的安全源的脚本,否则报错。禁止执行eval + inline script。使用方法如下:

<meta http-equiv="Content-Security-Policy" content="script-src self">

CSRF的防御

来源限制

若请求来源异常,则限制请求,一般是限制Origin和Referer,但是在同源请求中,GET和POST不发送Origin,所以使用Referer较多。

token

使用一个和具体用户关联的token进行操作,每次操作都需要携带token,但是需要注意过期时间的合理设置。

iframe攻击防范

对于来源限制,攻击者有可能会使用iframe进行同源请求,可以设置http响应头部X-Frame-Options: DENY/SAMEORIGIN。DENY指当前界面不能作为iframe加载,SAMEORIGIN设置为同源界面才能加载这个iframe

anti-pattern

不要将GET和POST混合到一个API上。

SameSite Cookie

如果当前域名为A,则只允许domain为A的Cookie,所以只允许这类Cookie发送到域名为A的服务器。

中间件

在node.js中,使用中间件对CSRF攻击进行防范。

注入攻击的防范

SQL注入攻击的防范

找到项目中使用SQL的地方,使用prepared statement

除SQL的注入攻击的防范

  • 最小权限原则,不要给sudo权限
  • 建立白名单,只允许指定的指令,过滤掉危险指令
  • 对URL类型参数,对协议、域名、ip等进行限制,避免攻击者访问内网资源。

DoS的防范

ReDoS的防范

  • 进行代码review,避免写出贪婪模式的代码
  • 代码扫描正则表达式,并进行性能测试
  • 拒绝使用用户提供的正则

DDoS

  • 流量治理:在负载均衡、API网关中,对来源进行过滤,如过滤掉来自同一地址的大量请求。还可以使用前置CDN。
  • 抗量:检测到大量请求后,又快速自动扩容机制,或者是非核心业务降级(或关闭)。

中间人攻击的防范

使用HTTPS协议,其三大特点是:

  1. 可靠性:加密,传输加密信息加密信息的hash,判断hash(加密信息) === 加密信息的hash
  2. 完整性:MAC验证
  3. 不可抵赖性: 数字签名,即公钥私钥加密

SRI(Subresourcce Integrity)

SRI就是在script标签中,设定加密算法和哈希值,如果资源经过这类加密算法得到的hash值和设定的一样,则认为没有被篡改。使用方式如下:

<script integrity="sha384-{some-hash-value}">

这类方法经常用于CDN内容的合法性进行校验,防止CDN内容被篡改。