← 返回新闻列表

警惕!源代码中的双向文本及隐藏字符可被用于特洛伊木马攻击

近期,GitHub在代码审查中引入一项警告,提示代码中可能存在的双向Unicode文本被恶意利用,制造视觉假象导致代码行为异变。攻击者可利用此类特征,如隐藏控制字符或同形字符,在源代码中植入难以察觉的后门或逻辑错误,从而绕过人工审查,构成新型安全威胁。

文 / 编辑部 · 2021/11/19 · 阅读约 3 分钟

分享:
警惕!源代码中的双向文本及隐藏字符可被用于特洛伊木马攻击

近期,GitHub的代码审查功能开始提示一项新警告:“This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below.”这条警告指向代码中存在的双向文本(bidirectional unicode),即在同一文件中混合使用从左到右和从右到左书写的文本。双向文本通常缩写为“BiDi”或“bidi”。对于使用中文的用户而言,双向文本并不陌生,因为中文书写方向同样可灵活变换。

早期计算机系统主要为基于拉丁字母的从左到右书写习惯设计。随着字符集和编码的扩展,虽然大多数从左到右的脚本得到支持,但对希伯来语或阿拉伯语等从右到左的脚本支持仍显不足,混合使用更是困难重重。后来,Unicode标准为双向文本提供了全面的支持,详细规定了如何编码和显示混合的从左到右与从右到左脚本,并可通过控制字符辅助排版。

理解双向文本后,我们来探讨为何GitHub会发出此类警告。GitHub官方博客指出,某些Unicode控制字符能够改变代码的视觉呈现,使其与实际执行逻辑产生偏差。

以一段Go语言代码为例,该代码表面上旨在计算“Hello, World”字符串中每个字符的二进制位中1的数量。然而,当直接执行这段代码,结果却是0。仔细检查该代码在字符界面编辑器(如vim)中的显示,会发现存在两个Unicode控制字符:U+202E(Right-to-Left Override [RLO])和U+202D(Left-to-Right Override [LRO])。

U+202E指令使后续文本以从右到左的方向显示,将“10x", 0”变为“0 ,"x01”。紧随其后的U+202D指令,又把部分文本从左到右显示,将“0 ,"x01”中的前四个字符“0 ,"”反转为“", 0”,最终导致代码在视觉上呈现为“"Hello, World!”, 0x01”,而实际逻辑则大相径庭,从而导致了意外的执行结果。

GitHub官方博客还提及一个安全漏洞——CVE-2021-42574。该漏洞源于Unicode 14.0规范中的双向算法问题,攻击者能利用控制序列重新排列字符的视觉顺序,使得源代码在视觉上与编译器或解释器执行的逻辑截然不同。这种技术可用于对接受Unicode的编译器源代码进行编码,在人眼难以察觉的情况下植入漏洞。

剑桥大学的一篇研究论文《Some Vulnerabilities are Invisible》详细描述了该安全问题。研究中展示了如何通过双向字符,将一段代码伪装。例如,一段看起来将“alice”资金从100减至50的代码,通过插入右到左隔离字符(RLI – U+2067),能在视觉上保持减法操作,但实际执行结果却维持100不变。

此外,Unicode的运用还会引发其他攻击形式,尤其是通过“不可见字符”或“同形字符”在源代码中埋下陷阱。例如,一个看似合法的JavaScript网络健康检查代码,其中包含不可见的Unicode字符(如ㅤ)。在特定编码环境下(如从Unicode改为DOS CP437),这些字符便会显现。攻击者可利用隐藏字符创建悄无声息的变量,再通过构造HTTP请求,将恶意命令注入并执行,从而形成隐蔽的后门。

另一种威胁是使用“同形字符”。例如,在代码中,“if(environmentǃ=ENV_PROD){return true;}”中的字符“ǃ”并非普通的感叹号,而是一个不同于标准感叹号的Unicode字符。这种同形字符即便是修改编码也难以发现其异常,因为它们在视觉上与正常字符几乎无法区分,使得人工审查难以奏效。因此,开发者应审慎检查代码,防范这类潜在的“特洛伊木马”攻击。

广告位 · 文末横幅