淘先锋技术网

首页 1 2 3 4 5 6 7

 

 

注意:HttpOnly解决的是XSS后的Cookie劫持攻击。因为JS读取不到Cookie的值。

 

 

一个Cookie的使用过程如下:

Step1:浏览器向服务器发起请求,这时候没有Cookie。

Step2:服务器返回时发送Set-Cookie头,向客户端浏览器写入Cookie。

Step3:在该Cookie到期前,浏览器访问该域下的所有页面,都将发送该Cookie。

HttpOnly是在Set-Cookie时标记的:

Set-Cookie: <name>=<value>[; <Max-Age>=<age>]
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; HttpOnly]

服务器可能会设置多个Cookie(多个key-value对),而HttpOnly可以有选择性地加在任何一个Cookie值上。

例,使用HttpOnly

<?php

header("Set-Cookie: cookie1=test1;");
header("Set-Cookie: cookie2=test2;httponly", false);

?>

<script>
  alert(document.cookie);
</script>

在这段代码中,cookie1没有HttpOnly,cookie2被标记为HttpOnly。两个Cookie均被写入浏览器。

在不同的语言中,给Cookie添加HttpOnly的代码如下

  • Java EE
response.setHeader("Set-Cookie", "cookiename=value;  Path=/;Domain=domainvalue;Max-Ag
e=seconds;HTTPOnly");
  • C#
HttpCookie myCookie = new HttpCookie("myCookie");
myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);
Dim myCookie As HttpCookie = new HttpCookie("myCookie")
myCookie.HttpOnly = True
Response.AppendCookie(myCookie)
  • .NET 1.1
Response.Cookies[cookie].Path += ";HTTPOnly";
  • PHP4
header("Set-Cookie: hidden=value; httpOnly");
  • PHP5
setcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE);

最后一个参数为HttpOnly属性。

HttpOnly不是万能的,添加了HttpOnly不等于解决了XSS问题。

XSS攻击带来的不光是Cookie劫持问题,还有窃取用户信息、模拟用户身份执行操作等诸多严重的后果。如前文所述,攻击者利用AJAX构造HTTP请求,以用户身份完成的操作,就是在不知道用户Cookie的情况下进行的。

使用HttpOnly有助于缓解XSS攻击,但仍然需要其他能够解决XSS漏洞的方案。

3-2. 输入检查

常见的Web漏洞如XSS、SQL Injection等,都要求攻击者构造一些特殊字符,这些特殊字符可能是正常用户不会用到的,所以输入检查就有存在的必要了。

输入检查的逻辑,必须放在服务器端代码中实现。如果只是在客户端使用JS进行输入检查,是很容易被攻击者绕过的。

客户端JS的输入检查,可以阻挡大部分误操作的正常请求,从而节约服务器资源。

在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如<、>、’、”等。如果发现存在特殊字符,则将这些字符过滤或者编码。

比较智能的输入检查,可能还会匹配XSS的特征。比如查找用户数据中是否包含了<script> 、javascript 等敏感字符。

这种输入检查的方式,可以称为XSS Filter。互联网上有很多开源的XSS Filter的实现。

XSS Filter的问题。

  • 问题1:语境

XSS Filter在用户提交数据时获取变量,并进行XSS检查;但此时用户数据并没有结合渲染页面的HTML代码,因此XSS Filter对语境的理解并不完整。

例,XSS 漏洞

<script src="$var" ></script>

其中$var是用户可以控制的变量。用户只需要提交一个恶意脚本所在的URL地址,即可实施XSS攻击。

如果是一个全局性的XSS Filter,则无法看到用户数据的输出语境,而只能看到用户提交了一个URL,很可能会漏报。因为在大多数情况下,URL是一种合法的用户数据。

  • 问题2:字符处理

对“<”、“>”等字符的处理,可能会改变用户数据的语义。

对于XSS Filter来说,发现了敏感字符“<”,如果XSS Filter不够“智能”,粗暴地过滤或者替换了“<”,则可能会改变用户原本的意思。

输入数据可能会被展示在多个地方,每个地方的语境可能各不相同,如果使用单一的替换操作,则可能会出现问题。

例,用户输入昵称

$nickname='我是"天才"'

XSS Filter对双引号进行转义

$nickname='我是\"天才\"'

HTML代码中展示如下

<div>我是\"天才\"<div>

JS代码中展示如下

<script>
var nick='我是\"天才\"';
document.write(nick);
</script>

这2段代码分别得到结果如下

第一个结果显然不是用户希望看到的。

3-3. 输出检查

没人不认识我:2021-2-5 《白帽子讲Web安全》笔记-3.XSS-输出检查

3-4. 正确防御

没人不认识我:2021-2-7 《白帽子讲Web安全》笔记-3.XSS-正确防御

3-5. 处理富文本

没人不认识我:2021-2-7 《白帽子讲Web安全》笔记-3.XSS-处理富文本

3-6.防御DOM Based XSS

没人不认识我:2021-2-7 《白帽子讲Web安全》笔记-3.XSS-防御DOM based XSS

3-7.从业务风险看XSS

前文谈到的所有XSS攻击,都是从漏洞形成的原理上看的。

而从业务风险看,存储型XSS的风险会高于反射型XSS。因为存储型XSS会保存在服务器上,有可能会跨页面存在。

它不改变页面URL的原有结构,因此有时候还能逃过一些IDS的检测。

例如:IE 8的XSS Filter和Firefox的Noscript Extension,都会检查地址栏中的地址是否包含XSS脚本。而跨页面的存储型XSS可能会绕过这些检测工具。

从攻击过程来说,反射型XSS,一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型XSS,则只需要让用户查看一个正常的URL链接。

例如:一个Web邮箱的邮件正文页面存在一个存储型的XSS漏洞,当用户打开一封新邮件时,XSS Payload会被执行。这样的漏洞极其隐蔽,且埋伏在用户的正常业务中,风险颇高

从风险的角度看,用户之间有互动的页面,是可能发起XSS Worm攻击的地方。而根据不同页面的PageView高低,也可以分析出哪些页面受XSS攻击后的影响会更大。

例如:在网站首页发生的XSS攻击,肯定比网站合作伙伴页面的XSS攻击要严重得多。

修补XSS漏洞时遇到的最大挑战之一是漏洞数量太多,因此开发者可能来不及,也不愿意修补这些漏洞。从业务风险的角度来重新定位每个XSS漏洞,就具有了重要的意义。

3-8.补充,3个防御措施

摘自XSS与CSRF的区别 - 抖音2020 - 博客园

1、编码:

 对用户输入的数据进行编码 

2、过滤:

 移除用户输入的和事件相关的属性 

如onerror可以自动触发攻击,还有onclick等。(总而言是,过滤掉一些不安全的内容)移除用户输入的Style节点、Script节点、Iframe节点。(尤其是Script节点,它可是支持跨域的呀,一定要移除)。

3、校正

避免直接对HTML Entity进行解码。使用DOM Parse转换,校正不配对的DOM标签 

 感谢你的观看,谢谢。