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

admin 2024年3月19日02:16:03评论4 views字数 5526阅读18分25秒阅读模式

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插入组件中。这个特性对于某些情况很有用,比如处理来自受信任来源的富文本内容。例如:

1functionMyComponent() {
2return<divdangerouslySetInnerHTML={{__html: '<h1>Hello World</h1>'}} />;
3}

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

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

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

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

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

1            <Row className="justify-content-between">
2<Colmd="6">3<RowclassName="justify-content-between align-items-center">4<div5dangerouslySetInnerHTML={{6__html: `
7 <imgsrc=${database.authorScreenshotURL}8alt=${9authorScreenshotDescription10 } />11 `,
12 }}
13 />
14</Row>

流入此组件的变量 `authorScreenshotDescription` 是由用户控制的,用于指定图像的文本描述。攻击者可能利用这个跨站脚本漏洞,在浏览器中通过将 `authorScreenshotDescription` 变量的值设置为以下内容来实现 JavaScript 代码执行: `"<img src=x onError=alert(1)`。但是,作为一名负责任的开发人员,您明白:

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

  • 您知道,如果您确实需要使用这个 React API,您必须实现安全的输出编码来转义危险字符,比如 `<`,这样可以让您创建 HTML 元素。

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

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

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

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

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

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

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

我们还没有走出危险。

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

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

1s "<img src=x onLoad=alert(1)

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

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

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

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

这样做并应用先前起作用的攻击有效负载`s "<img src=x onLoad=alert(1)`,我们可以观察到,即使在尝试转义有效负载中的引号字符并关闭`alt`属性值时,我们的攻击有效负载有一个额外的闭合双引号字符,这会阻碍JavaScript执行:

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

看起来很棒。

直到... 

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

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

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

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

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

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

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

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

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

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

1s "<img src=x onError=alert(1)

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

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

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

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

1s onLoad=alert(1)

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

突出React XSS安全问题

尽管这次对HTML转义函数的尝试很全面,但却错过了输出转义和通用消毒安全逻辑的一个基本原则——上下文至关重要。数据流入敏感API的上下文中,在本例中,属性值是HTML属性形式,而不是HTML元素形式。我们能够仅仅使用一个空格字符来表达alt属性的结束和下一个属性onLoad的开始这一事实,正是问题的核心。

在 React 应用程序中防范跨站脚本攻击

在保护 React 应用程序免受跨站脚本的影响的同时,像 GitHub Copilot 这样的工具正在彻底改变软件开发领域,但必须牢记,这些 AI 模型有时可能会建议不安全的代码。因此,拥有强大的安全防护措施对于保护您的应用程序至关重要。这正是开发人员安全工具如 Snyk 的用武之地。Snyk 是开发人员安全工具领域中备受尊重的名字,提供一个便捷的 IDE 扩展程序。在编写 React 代码时,Snyk 可以发现潜在的安全漏洞,例如 Copilot 可能无法捕获的 'dangerouslySetInnerHTML' 的不安全使用所引起的风险。这种实时保护措施对帮助您编写安全的 React 应用程序并防止跨站脚本攻击至关重要。

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

Snyk的一个关键特色是DeepCode AI。DeepCode利用AI技术扫描您编写的代码,识别代码中的安全、性能和逻辑问题。但它不仅止步于识别潜在问题。DeepCode AI还提供AI Fix,为识别出的问题提供自动生成的修复方案,使您更容易编写安全高效的代码。

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

Snyk是一个免费工具,旨在帮助开发人员在他们的集成开发环境(IDE)中编写更安全的代码。在您使用GitHub Copilot等AI辅助编码工具时,Snyk等辅助工具的补充保护将成为宝贵的资产。

除了使用Snyk之外,还应遵循以下网络应用程序安全实践。其中一项安全控制与执行安全的输出编码有关。

在前端Web应用程序中减轻此类安全风险需要对流入敏感API(例如dangerouslySetInnerHTML)的用户输入进行仔细的清理。始终将用户输入视为不可信,因此来自用户的任何HTML内容都需要经过强大的HTML清理过程。为此,可以利用一些第三方库,例如DOMPurify:

1import DOMPurify from"dompurify";
2
3functionMyComponent({userInput}) {
4const cleanInput = DOMPurify.sanitize(userInput);
5return<divdangerouslySetInnerHTML={{__html:cleanInput}} />;
6}

此外,如果您只是想呈现文本内容,请考虑替代dangerouslySetInnerHTML的方法,例如使用React的文本内容处理,使用花括号{}。

总结起来,虽然AI建议可以加快您的编码过程,但人类的警惕和强大的安全工具仍然是创建安全应用程序不可或缺的部分。

此外,请记住,即使dangerouslySetInnerHTML提供了在React中处理HTML的方法,了解其潜在的安全影响是至关重要的。谨慎使用并清理流入其中的数据可以帮助保持您的React应用程序免受XSS漏洞的威胁。

我强烈建议您尝试一下Snyk,看看它的实时漏洞评估和自动修复如何提高您的React应用程序的安全性,进而提升您作为一位重视构建安全软件的工程师的生产力。俗话说,预防胜于治疗,尤其是在涉及安全编码时。

原文始发于微信公众号(黑伞安全):GitHub Copilot代码安全性:React中的XSS

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月19日02:16:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   GitHub Copilot代码安全性:React中的XSShttps://cn-sec.com/archives/2586053.html

发表评论

匿名网友 填写信息