专栏名称: 黑伞安全
安全加固 渗透测试 众测 ctf 安全新领域研究
目录
相关文章推荐
新疆949交通广播  ·  老人刷视频导致2300度近视?这些习惯,正在 ... ·  11 小时前  
新疆949交通广播  ·  《哪吒2》,破130亿! ·  昨天  
新疆949交通广播  ·  26945个,新能源车主看过来! ·  2 天前  
新疆949交通广播  ·  新疆这座机场,有新进展! ·  2 天前  
中核集团  ·  校园招聘🤩 ·  3 天前  
51好读  ›  专栏  ›  黑伞安全

GitHub Copilot代码安全性:React中的XSS

黑伞安全  · 公众号  ·  · 2024-03-18 18:21

正文

2023年10月19日 阅读时间:13分钟

原文:https://snyk.io/blog/github-copilot-xss-react/

在人工智能(AI)和大型语言模型(LLMs)不断发展的时代,GitHub Copilot等创新工具正在改变软件开发的格局。在先前的一篇文章中,我谈到了这种变革的影响,以及它如何延伸到这些智能自动化工具所提供的便利性,以及它给我们编码实践中维护强大安全性带来的新一套挑战。Snyk还发布了关于使用AI编码时的安全风险的案例研究。在这篇文章中,我们旨在探讨在React代码库中使用GitHub Copilot时的安全性方面,以及它如何在前端开发人员的React组件JSX文件中为他们自动补全代码。我们的目标是检查GitHub Copilot提出的代码是否符合安全编码原则,帮助开发人员编写成功规避潜在跨站脚本(XSS)漏洞的代码,尤其在React开发环境中。对于不熟悉XSS严重后果的人来说,它们基本上允许攻击者将客户端脚本注入其他用户查看的网页中。

Developers adopt GitHub Copilot


开发人员采用 GitHub Copilot 在人工智能对各个领域产生影响的领域中,软件开发占据了一个值得注意的位置。在这一领域中出现的新兴创新之一是 GitHub Copilot,这是一款开发人员工具,内置在开发环境中,例如 VS Code,由 OpenAI 的 Codex 提供支持。GitHub Copilot 的设计是作为您的人工智能协作开发者。它能够提供编码建议,编写整行或整块代码,并兼容多种编程语言 — 这种功能也适用于流行的前端库和框架,比如 React。随着 Copilot 在我们的开发者工具箱中变得越来越受到依赖,我们必须能够信任它所建议的代码的语法,但我们还需要确保这段代码足够安全,能够符合我们所实践的标准,并且不会危害用户。通过 JavaScript 代码示例和对 JSX 和 React 特定安全实践的深入研究,本文旨在不仅仅是为了通知,而且为了让开发人员评估和利用这些经过人工智能增强的开发工具,而不会损害应用程序安全。


危险区域:使用React的dangerouslySetInnerHTML函数React提供了一个API,让开发者可以直接从React组件中设置HTML — dangerouslySetInnerHTML函数。正如其名称所示,使用这个函数可能会很危险。它的工作原理是绕过React中执行输出编码的安全控制,以帮助防止跨站脚本攻击,允许您手动将HTML插入组件中。这个特性对于某些情况很有用,比如处理来自受信任来源的富文本内容。例如:


1function MyComponent() {
2 return <div dangerouslySetInnerHTML={{__html: '<h1>Hello Worldh1>'}} />;
3}


尽管这提供了一种快速直接的处理 HTML 内容的方式,但也会将您的应用程序暴露于跨站脚本 (XSS) 攻击的风险之下。假设用户提供的数据是 `dangerouslySetInnerHTML` 设置的 HTML 内容的一部分,攻击者可以注入一个将被执行的任意脚本 — 潜在影响可能非常广泛。

1function MyComponent({userInput}) {
2 // This can expose the application to XSS risks if userInput contains a malicious script.
3 return <div dangerouslySetInnerHTML={{__html: userInput}} />;
4}

因此,在应用程序中使用 `dangerouslySetInnerHTML` 时必须谨慎。


GitHub Copilot是否提供安全的代码建议?

GitHub Copilot 可以帮助开发人员实现一些安全控制,以减轻在 `dangerouslySetInnerHTML` 中发生 XSS 的可能性吗?让我们考虑以下使用 `dangerouslySetInnerHTML` 指令的 React 组件代码:

1            "justify-content-between">
2 <Col md="6">
3 <Row className="justify-content-between align-items-center">
4 <div
5 dangerouslySetInnerHTML={{
6 __html: `
7 <img src=${database.authorScreenshotURL}
8 alt=${
9 authorScreenshotDescription
10 } />
11 `,
12 }}
13 />
14 Row>

流入此组件的变量 `authorScreenshotDescription` 是由用户控制的,用于指定图像的文本描述。攻击者可能利用这个跨站脚本漏洞,在浏览器中通过将 `authorScreenshotDescription` 变量的值设置为以下内容来实现 JavaScript 代码执行: `"

  • 你确实不应该使用 `dangerouslySetInnerHTML`,就像名字暗示的那样——这是很危险的!但是有一种特定情况需要您使用它,所以:

  • 您知道,如果您确实需要使用这个 React API,您必须实现安全的输出编码来转义危险字符,比如 `

那么接下来怎么办呢?您开始为这个 React 组件编写一个快速的跨站脚本转义函数。当然,GitHub Copilot 在那里帮助您。


当您开始输入函数名称及其参数时,正要开始编写函数体时,GitHub Copilot会自动建议以下代码。看起来很不错。您只需按TAB键即可。当然,别忘了更新我们在组件中使用`dangerouslySetInnerHTML` API,以使用此安全转义函数:

尝试相同的 XSS 攻击,攻击者之前成功的攻击。我们发现它失败了。

显然,GitHub Copilot建议的代码自动补全`escapeCrossSiteScripting`函数效果神奇,确实转义了先前创建了新的` ` HTML元素并执行JavaScript代码的尖括号。

我们还没有走出危险。

攻击者是坚持不懈的,对他们来说几乎没有成本可自动化他们的攻击有效负载。因此,他们可能会通过数千种字符串排列的迭代,通常被称为模糊测试,在找到有效的一种方式之前进行尝试。这就是计算机黑客技术发展的地方 - 开发人员需要从每个潜在故障点保护,而攻击者只需要找到一种方式进入,尽管它很微小。

因此,攻击者可能尝试以下有效负载:

1s \"

在上述情况下,我们将`onError`属性处理程序更改为`onLoad`处理程序。现在,如果我们再次加载网页,我们将观察到这次攻击成功,弹出了一个弹窗:

作为开发人员,您会想知道这种安全漏洞是如何发生的,以及如何避免它。一位经验丰富的 React 开发人员可能会告诉您,在代码安全性方面,将属性的值用引号括起来是一种更优越的编码约定,因此让我们这样做,并在下面的 `alt=` 属性值中应用此更改:

1     
2 dangerouslySetInnerHTML={{
3 __html: `
4 ${database.authorScreenshotURL}
5 alt="${escapeCrossSiteScripting(
6 authorScreenshotDescription
7 )}" />
8 `,
9 }}
10 />

这样做并应用先前起作用的攻击有效负载`s "

看起来很棒。

直到...

攻击者找到了一种创造性的方式,以一个更短的负载形式逃离这种情况,保持 `onLoad` 特殊属性的滥用,并注入一个分号和一个 `//` 字符串,表示任何尾随字符串应被视为注释。使用以下负载:

1s \" onLoad=alert(1); //


欢迎来到另一次成功执行跨站脚本攻击:

但是如果我们尝试不同的方法呢?如果我们不在 'dangerouslySetInnerHTML' 部分用双引号括住 `alt=` 属性,而是尝试彻底重构转义函数呢?让我们尝试这样做。所以,我们的 React 组件的 JSX 代码仍然如下所示:

1  
2 dangerouslySetInnerHTML={{
3 __html: `
4 ${database.authorScreenshotURL}
5 alt=${escapeHTML(
6 authorScreenshotDescription
7 )} />
8 `,
9 }}
10 />

接下来,我们想重构现有的 'escapeCrossSiteScripting',使其成为一个更安全、更详尽地处理字符编码的HTML转义函数,而不仅仅是 '' 和 '&'。所以,我们开始输入代码,当然,GitHub Copilot 醒来并提供以下建议:

它实际上建议整个函数体代码,我只是简单地提示它继续完成代码建议,直到我们完成这个净化。看起来像是一个更好的输出编码逻辑,考虑了其他危险字符,如单引号和双引号。

如果我们向应用程序提供我们的原始有效负载:

1s \"

GitHub Copilot 提供的代码确实对所有潜在危险字符进行了编码,包括攻击有效荷载试图逃逸的双引号:

然而,我们又错了,因为如下简单的攻击载荷仍会触发跨站脚本,从而允许执行任何 JavaScript 代码

然而,我们还是会再次错了,因为如下简单的攻击有效负载仍然会触发跨站脚本,从而允许执行任何 JavaScript 代码:

1s onLoad=alert(1)

为什么会发生这种情况呢?







请到「今天看啥」查看全文


推荐文章
新疆949交通广播  ·  《哪吒2》,破130亿!
昨天
新疆949交通广播  ·  26945个,新能源车主看过来!
2 天前
新疆949交通广播  ·  新疆这座机场,有新进展!
2 天前
中核集团  ·  校园招聘🤩
3 天前
伊思爱情顾问  ·  和男人硬碰硬是最蠢的做法
8 年前
汽车电商笔记  ·  竟然使出这招,摩拜被逼得不行了?
7 年前