结构化输出生成漏洞
程序通常必须动态构造结构化输出,然后由另一个程序使用。示例包括:构造数据库使用的SQL查询,或构造Web浏览器使用的HTML页面。可以将生成结构化输出的代码视为子组件。输出的预期结构,以及如何在输出中使用子组件的输入,可以被视为该子组件应遵守的协定。例如,当提供名称和密码作为输入时,预期的输出是一个SQL查询,该查询从用户中选择具有给定名称和密码的用户数据库表。
一种常见的不安全编程实践是通过字符串操作来构造这种结构化输出。输出构造为字符串的串联,其中其中一些字符串是从程序的输入派生的(直接或间接)。这种做法很危险,因为它使输出字符串的预期结构成为隐式的,并且恶意选择输入字符串的值可能会导致程序生成意外的输出。例如,程序员可以将SQL查询构造为:
query=”select * from users where name=’” + name + ”’” and pw = ’” + password + ”’”
目的是构造一个SQL查询,用于检查where子句中的名称和密码。但是,如果名称字符串由攻击者提供,则攻击者可以将名称设置为“John'--”,这将从查询中删除密码检查(注意-在SQL中开始注释)。
结构化输出生成漏洞是程序构造此类意外输出的错误。在结构化输出表示旨在将提供的输入作为数据包含的代码的情况下,这尤其危险。然后,恶意选择的输入数据可能会以意外的方式影响生成的输出代码。这些漏洞也称为注入漏洞(例如,SQL注入或脚本注入)。名称“注入”是指利用这些漏洞通常会提供数据输入,导致结构化输出包含额外的代码语句,即利用在输出中注入意外的新语句。结构化输出生成漏洞与许多不同类型的结构化输出相关:
• SQL注入漏洞是一种结构化输出生成漏洞,其中结构化输出由SQL代码组成。这些漏洞与服务器端Web应用程序软件特别相关,在服务器端Web应用程序软件中,应用程序通常通过部分基于Web表单提供的输入构造查询来与后端数据库进行交互。
• 命令注入漏洞是一个结构化输出生成漏洞,其中结构化输出是应用程序发送到操作系统shell的shell命令。
• 脚本注入漏洞(有时也称为跨站点脚本(XSS)漏洞)是一种结构化输出生成漏洞,其中结构化输出是发送到Web浏览器进行客户端执行的JavaScript代码。
此列表绝不是详尽无遗的。其他例子包括:XPath注入,HTML注入,CSS注入,PostScript注入等等。
有几个因素可能导致难以避免结构化输出生成漏洞:
• 结构化输出可以是支持句法结构明显不同的子语言的语言。这种问题案例的一个重要例子是HTML,它支持JavaScript,CSS和SVG等子语言。
• 结构化输出的计算可以在不同的阶段进行,一个阶段的输出被存储,然后作为后续阶段的输入进行检索。经历多个阶段的结构化输出生成漏洞有时称为存储注入漏洞,或者更一般地称为高阶注入漏洞。示例包括存储的XSS和高阶SQL注入。
利用结构化输出生成漏洞的攻击技术通常取决于结构化输出语言的性质,但已知并记录了用于利用SQL注入或脚本注入的各种攻击技术。
Web和移动安全CyBOK知识区[2]提供了对此类攻击技术的更详细讨论。