Web安全

244 阅读6分钟

XSS

Cross-Site Scripting(跨站脚本攻击),是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在浏览器运行。利用这些恶意脚本,攻击者可以获取用户的敏感信息,如Cookie、SessionID等,进而危害数据安全。

任何可以输入的地方,都可能造成XSS攻击,包括URL。

常见的XSS目的:盗取cookie、投放广告、监听用户行为、修改DOM结构获取用户信息。

XSS的分类

根据攻击来源,可以分为3类:存储型、反射型、DOM型。

存储型XSS(持久性)
  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 当用户打开网站,网站服务端将恶意代码调出,拼接在HTML中返回给浏览器。
  3. 浏览器解析执行,混在其中的恶意脚本也被执行。
  4. 该恶意脚本窃取用户数据发送到攻击者的网站,或冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

常见于带有用户数据保存的网站功能。比如攻击者在网站上提交一篇有恶意脚本的文章,被存到了数据库,当用户访问这个文章,浏览器解析到这段恶意脚本,就会执行。

反射型XSS(非持久性)
  1. 攻击者构造初特殊的URL,其中包含恶意代码。
  2. 诱导用户打开带有恶意代码的URL,网站服务器端不对这个url参数过滤处理,简单的“反射”给浏览器。
  3. 浏览器解析执行,混在其中的恶意脚本也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

它和存储型XSS的区别是:存储型XSS的恶意代码保存在数据库中,而反射型XSS保存在URL中。

常见于通过URL传参的功能,如网站搜索、跳转、QQ邮件中的一些恶意链接等。

DOM型XSS
  1. 基于浏览器解析DOM导致的漏洞,并不依赖于服务器
  2. 用户点击一个带有恶意脚本的URL
  3. 浏览器在DOM解析的时候直接使用了恶意数据
  4. 导致用户受到攻击

DOM型XSS和前两种的区别:DOM型XSS取出和执行恶意代码由浏览器完成,属于前端JS自身安全漏洞,而前两种是服务器的安全漏洞。防范DOM型XSS完全是前端的责任。

比如说:前端把某个元素的.innerHTML设置为一个输入框的相关数据,当恶意攻击者在输入框输入恶意脚本,这个脚本会被执行。

XSS Payload

有效的XSS攻击,包括:

  • 窃取用户的Cookie (document.cookie)
  • 识别用户的浏览器 (navigator.userAgent)
  • 伪造请求
  • 钓鱼网站 (在页面中注入钓鱼网站链接,诱导用户点击)

常见XSS防范方法

  • 设置httpOnly:这样js脚本就无法获取cookie的信息了。
  • 设置黑名单,对不安全的输入进行过滤和转码,把<script>标签、javascript等字符过滤掉
  • 设置白名单,只有符合相应格式的输入才能通过
  • 利用CSP,明确表示哪些外部资源是可以加载和执行的
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

或者设置http头部字段:Content-Security-Policy

  • X-XSS-Protection

    在http的响应头中设置该字段:

    0:禁用XSS过滤

    1:启用XSS过滤(默认),当检测到XSS攻击,会删除页面中不安全的部分

    1;mode=block:当检测到XSS攻击,会阻止页面的加载

    1; report=:当检测到攻击,会清除页面并且使用CSP的功能发送违规报告。

预防DOM型XSS攻击

  • 小心使用.innerHTML .outerHTML document.write(),不要把不可信数据作为HTML插到页面上,尽量使用.textContent .setAttribute()
  • 在Vue和React中,不要使用v-html、dangerouslySetInnerHTML,这样就在前端render阶段避免了XSS隐患。
  • DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。

CSRF(Cross-Site request forgery)

跨站点请求伪造,是一种挟制用户在当前已登录的Web应用程序上执行非本意操作的攻击。如:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

常见CSRF类型

GET类型的CSRF
<img src="http://bank.example/withdraw?amount=10000&for=hacker" > 

当用户打开有这张图片的页面,浏览器就会自动向bank这个网站发起HTTP请求。

POST类型的CSRF

使用一个自动提交的表单。

<form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 

访问该页面后,表单自动提交,相当于模拟用户进行了一次POST操作。

链接类型的CSRF
 <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
  <a/>

CSRF的特点

  • 攻击一般发起在第三方网站,被攻击的网站无法阻止发生
  • 利用了受害者在被攻击网站的登陆凭证,冒充受害者提交操作
  • 跨站请求可以用各种方式:图片URL、超链接、Form提交等。

CSRF和XSS的区别

  • 有时候,CSRF是由XSS实现的(蠕虫) 。
  • 本质上说,XSS是代码注入的问题,CSRF是HTTP的问题。XSS是因为内容上没有过滤导致浏览器将攻击者的代码执行。CSRF则是因为浏览器发送HTTP的时候自动带上Cookie,而一般网站的session都存在cookie里。

防御

  • 防止用户不知情的情况下盗用了用户的身份

    验证码:强制用户必须与应用进行交互,才达成最终请求。

    用户体验不好

  • 防止跨站请求

    Refer check:通过request header的referer字段,查看请求来自哪个源

    不可靠,依然可能被篡改

  • 防止参数伪造

    token(常用):前后端协商一个token加密的算法,当前端发起请求的时候,带上token,后端收到请求后,用同样的方式算出用户对应的token,如果一致,才通过验证。

  • sameSite:在服务器通过set-cookie返回响应的时候,可以设置samesite属性的值为strict

samesite

strict:完全禁止发送第三方Cookie,只有当前URL和请求目标一致才带上Cookie

lax:允许发送Get请求的第三方Cookie

none:允许发送所有Cookie,但cookie要用secure属性,否则无效

第一方Cookie:用户访问的域创建的Cookie。

第三方Cookie:建立在别的域名下的Cookie,比如广告网络商是最常见的第三方Cookie来源。

DDOS攻击

通过大规模互联网流量淹没目标服务器或其周边基础设施,以破坏目标服务器、服务或网络正常流量的恶意行为。

就好比一家餐厅原本能同时容纳30个人,但有一天,一个流氓带着300个人进了餐厅,占着位置但是却不点餐,导致正常的顾客页无法光顾,餐厅瘫痪了。

DDOS防范

  • 验证码:降低用户体验
  • 限制请求频率:通过一些标识(IP或Cookie)定位客户端,限制一个客户端请求的频率
  • 扩容加带宽:适合双十一活动或12306抢车票等场景

网页劫持

DNS劫持

解析域名时,服务提供商可能会对IP地址劫持,返回一个错误的IP地址。

HTTP劫持

DNS劫持一般会替换整个网页,而http劫持,利用了http协议明文传输的特点,篡改了返回的html内容。

常见的场景是在页面加一个小窗,可能投放广告。

这是由于信息没有加密而造成的。可以使用HTTPS解决。

路由劫持

比如:小米路由器,把404之类的页面换成自己的页面。 Web中的攻击方式主要有XSS、CSRF、DDOS、HTTP劫持等

软件劫持

使用一些软件来清除广告,但这会管控全局流量,电脑的所有网络流量都会经过这个软件,所以进行劫持也是很简单的事情。