Skip to content

Injection Prevention Cheat Sheet / 注入防护速查表

Introduction / 介绍

This article is focused on providing clear, simple, actionable guidance for preventing injection flaws in your applications. Injection attacks, for example SQL Injection, are unfortunately very common.

本文旨在提供清晰、简单、可操作性的指导,以防止应用程序中的注入漏洞。例如,注入攻击(如 SQL注入)非常常见,令人遗憾的是非常普遍。

Application accessibility is a very important factor in protection and prevention of injection flaws. Only the minority of all applications within a company/enterprise are developed in house, where as most applications are from external sources. Open source applications give at least the opportunity to fix problems, but closed source applications need a different approach to injection flaws.

应用程序的可访问性是保护并预防注入漏洞的一个重要因素。在公司/企业中,只有少数应用程序是内部开发的,而大多数应用程序来自外部来源。开源应用程序至少提供了修复问题的机会,但封闭源代码应用程序需要不同的方法来处理注入漏洞。

Injection flaws occur when an application sends untrusted data to an interpreter. Injection flaws are very prevalent, particularly in legacy code, often found in SQL queries, LDAP queries, XPath queries, OS commands, program arguments, etc. Injection flaws are easy to discover when examining code, but more difficult via testing. Scanners and fuzzers can help attackers find them.

注入漏洞发生在应用程序将不受信任的数据发送到解释器时。注入漏洞非常普遍,尤其是在遗留代码中,通常出现在SQL查询、LDAP查询、XPath查询、操作系统命令、程序参数等地方。在检查代码时,注入漏洞很容易被发现,但通过测试则更困难。扫描器和模糊测试工具可以帮助攻击者找到它们。

Depending on the accessibility different actions must be taken in order to fix them. It is always the best way to fix the problem in source code itself, or even redesign some parts of the applications. But if the source code is not available or it is simply uneconomical to fix legacy software only virtual patching makes sense.

根据可访问性的不同,必须采取不同的行动来修复它们。始终在源代码本身中修复问题,或者甚至重新设计应用程序的一些部分,这是最好的方法。但如果源代码不可用,或者修复遗留软件的成本太高,那么仅虚拟打补丁才是合理的。

Application Types / 应用程序类型

Three classes of applications can usually be seen within a company. Those 3 types are needed to identify the actions which need to take place in order to prevent/fix injection flaws.

在公司中通常可以看到三类应用程序。这3种类型需要确定需要采取哪些行动来防止/修复注入漏洞。

A1: New Application / A1: 新应用程序

A new web application in the design phase, or in early stage development.

处于设计阶段或早期开发阶段的新网络应用程序

A2: Productive Open Source Application / A2:生产型开源应用程序

An already productive application, which can be easily adapted. A Model-View-Controller (MVC) type application is just one example of having a easily accessible application architecture.

一个已经投入使用的应用程序,可以轻松地进行适配。一个模型-视图-控制器(MVC)类型的应用程序是易于访问的应用架构的一个例子。

A3: Productive Closed Source Application / A3:生产型闭源应用程序

A productive application which cannot or only with difficulty be modified.

一个无法修改或只能困难修改的生产型应用程序。

Forms of Injection / 注入类型

Use the guidance for the query language or interpreter your application uses:

使用您应用程序使用的查询语言或解释器的指南:

Type / 类型 When Reference / 参考
SQL injection
SQL注入
Builds SQL queries
构建 SQL 查询
SQL Injection Prevention and Query Parameterization
SQL 注入防护 和 查询参数化
Object-relational mapper query injection
对象关系映射查询注入
Builds query strings with tools such as Hibernate
使用 Hibernate 等工具构建查询字符串
SQL Injection Prevention and Query Parameterization
SQL 注入防护 和 查询参数化
NoSQL injection
NoSQL 注入
Builds queries for a NoSQL database
为 NoSQL 数据库构建查询
NoSQL Security
NoSQL 安全
Cross-site scripting (XSS)
跨站脚本(XSS)
Places untrusted data into browser content
将不受信任的数据放入浏览器内容中
Cross Site Scripting Prevention and DOM based XSS Prevention
跨站脚本预防 和 基于 DOM 的 XSS 预防
LDAP injection
LDAP注入
Builds LDAP queries
构建 LDAP 查询
LDAP Injection Prevention
LDAP 注入预防
XPath injection
XPath 注入
Builds XPath queries
构建 XPath 查询
XPath Injection Prevention
XPath 注入预防
OS command injection
操作系统命令注入
Invokes operating system commands
调用操作系统命令
OS Command Injection Defense
操作系统命令注入防御
Argument injection
参数注入
Passes untrusted input as command arguments
将不受信任的输入作为命令参数传递
Argument Injection
参数注入

For Java-specific guidance, see Injection Prevention in Java.

关于Java特定的指导,请参阅Java注入防护。

Query languages / 查询语言

LDAP Injection / LDAP注入

LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements through techniques similar to SQL Injection. LDAP injection attacks could result in the granting of permissions to unauthorized queries, and content modification inside the LDAP tree. For more information on LDAP Injection attacks, visit LDAP injection.

LDAP注入是一种攻击,用于利用基于Web的应用程序,这些应用程序根据用户输入构建LDAP语句。当应用程序未能正确清理用户输入时,可以通过类似于SQL注入的技术修改LDAP语句。LDAP注入攻击可能导致授权未经授权的查询,以及LDAP树内的内容修改。有关LDAP注入攻击的更多信息,请访问LDAP注入。

LDAP injection) (LDAP注入) attacks are common due to two factors:

  1. The lack of safer, parameterized LDAP query interfaces
    中文:缺乏更安全的参数化LDAP查询接口
  2. The widespread use of LDAP to authenticate users to systems.
    中文:LDAP在用户系统认证中的广泛应用
How to test for the issue / 如何测试该问题
During code review / 代码审查期间

Please check for any queries to the LDAP escape special characters, see here.

请检查是否有查询LDAP时转义特殊字符的代码,请参阅此处。

Automated Exploitation / 自动化利用

Scanner module of tool like OWASP ZAP have module to detect LDAP injection issue.

OWASP ZAP等工具的扫描模块具有检测LDAP注入问题的模块。

Remediation / 修复措施
Use the right LDAP encoding function / 使用正确的LDAP编码函数

LDAP distinguished names and LDAP search filters require different escaping rules, defined by RFC 4514 and RFC 4515, respectively. Avoid custom escaping code and use a library encoder for the correct context. See the LDAP Injection Prevention Cheat Sheet for current defenses and examples.

LDAP区分名称和LDAP搜索过滤器需要不同的转义规则,分别由RFC 4514和RFC 4515定义。避免使用自定义转义代码,并在正确上下文中使用库编码器。请参阅LDAP注入预防备忘单以获取当前防御措施和示例。

XPath Injection / XPath注入

See the XPath Injection Prevention Cheat Sheet for defenses and a parameterized query example.

查看XPath注入防御技巧表以获取防御措施和参数化查询示例。

Scripting languages / 脚本语言

All scripting languages used in web applications have a form of an eval call which receives code at runtime and executes it. If code is crafted using unvalidated and unescaped user input code injection can occur which allows an attacker to subvert application logic and eventually to gain local access.

所有在Web应用程序中使用的脚本语言都包含一种eval调用形式,它在运行时接收代码并执行。如果使用未经验证和转义的用户输入编写的代码,则可能发生代码注入,攻击者可以绕过应用程序逻辑,最终获得本地访问权限。

Every time a scripting language is used, the actual implementation of the 'higher' scripting language is done using a 'lower' language like C. If the scripting language has a flaw in the data handling code 'Null Byte Injection' attack vectors can be deployed to gain access to other areas in memory, which results in a successful attack.

每次使用脚本语言时,'更高'级脚本语言的实际实现都是使用'C'等'更低'级语言完成的。如果脚本语言在数据处理代码中存在漏洞,则可以通过'空字节注入'攻击向量来获取对内存中其他区域的访问权限,从而导致攻击成功。

Operating System Commands / 操作系统命令

OS command injection is a technique used via a web interface in order to execute OS commands on a web server. The user supplies operating system commands through a web interface in order to execute OS commands.

操作系统命令注入是通过Web界面执行Web服务器上的操作系统命令的技术。用户通过Web界面提供操作系统命令以执行这些命令。

Any web interface that is not properly sanitized is subject to this exploit. With the ability to execute OS commands, the user can upload malicious programs or even obtain passwords. OS command injection is preventable when security is emphasized during the design and development of applications.

任何未正确清理的Web界面都容易受到这种攻击。有了执行操作系统命令的能力,用户可以上传恶意程序或甚至获取密码。在应用程序的设计和开发过程中强调安全性时,可以预防操作系统命令注入。

How to test for the issue / 如何测试该问题

During code review / 代码审查期间

Check if any command execute methods are called and in unvalidated user input are taken as data for that command.

检查是否有任何命令执行方法被调用,并且未经验证的用户输入被用作该命令的数据。

Out side of that, appending a semicolon to the end of a URL query parameter followed by an operating system command, will execute the command. %3B is URL encoded and decodes to semicolon. This is because the ; is interpreted as a command separator.

除此之外,在URL查询参数末尾添加分号,后跟操作系统命令,将执行该命令。%3B是URL编码,解码后为分号。这是因为;被解释为命令分隔符。

Example: http://sensitive/something.php?dir=%3Bcat%20/etc/passwd

例如:http://sensitive/something.php?dir=%3Bcat%20/etc/passwd

If the application responds with the output of the /etc/passwd file then you know the attack has been successful. Many web application scanners can be used to test for this attack as they inject variations of command injections and test the response.

如果应用程序响应/etc/passwd文件的输出,那么你知道攻击已经成功。许多Web应用程序扫描器可以用来测试这种攻击,因为它们会注入命令注入的变体并测试响应。

Equally Static Code Analysis tools check the data flow of untrusted user input into a web application and check if the data is then entered into a dangerous method which executes the user input as a command.

同样,静态代码分析工具检查不受信任的用户输入在Web应用程序中的数据流,并检查数据是否随后被输入到危险的执行用户输入作为命令的方法中。

Remediation / 修复措施

If it is considered unavoidable the call to a system command incorporated with user-supplied, the following two layers of defense should be used within software in order to prevent attacks

如果认为调用系统命令与用户提供的输入不可避免,那么在软件中应使用以下两层防御措施来防止攻击

  1. Parameterization - If available, use structured mechanisms that automatically enforce the separation between data and command. These mechanisms can help to provide the relevant quoting, encoding.
    中文:参数化 - 如果可用,使用自动强制数据与命令之间分离的结构化机制。这些机制可以帮助提供相关的引号、编码。
  2. Input validation - the values for commands and the relevant arguments should be both validated. There are different degrees of validation for the actual command and its arguments:
    中文:输入验证 - 命令及其相关参数的值都应该进行验证。实际命令及其参数的验证程度不同:
    • When it comes to the commands used, these must be validated against a list of allowed commands.
      中文:当涉及到命令时,这些必须与允许的命令列表进行验证。
    • In regards to the arguments used for these commands, they should be validated using the following options:
      中文:关于这些命令使用的参数,应使用以下选项进行验证:
      • Positive or allowlist input validation - where are the arguments allowed explicitly defined
        中文:正则或允许列表输入验证 - 明确定义了参数允许的位置
      • Allow-list Regular Expression - where is explicitly defined a list of good characters allowed and the maximum length of the string. Ensure that metacharacters like & | ; $ > < \ \ !and whitespaces are not part of the Regular Expression. For example, the following regular expression only allows lowercase letters and numbers, and does not contain metacharacters. The length is also being limited to 3-10 characters: <br>*中文:允许列表正则表达式 - 明确定义了允许的字符列表和字符串的最大长度。确保正则表达式中的元字符如& | ; $ > < ` \ !`和空格不是正则表达式的一部分。例如,以下正则表达式只允许小写字母和数字,且不包含元字符。长度也被限制在3-10个字符之间:*

^[a-z0-9]{3,10}$

Example code - Java / 示例代码 - Java

Incorrect Usage / 错误用法
ProcessBuilder b = new ProcessBuilder("C:\\DoStuff.exe -arg1 -arg2");

This creates a builder with one command-list element, not a program followed by two arguments. ProcessBuilder represents the executable and its arguments as a list. The snippet does not start a process or demonstrate shell-command injection.

这创建了一个包含一个命令列表元素的构建器,而不是一个程序后跟两个参数。ProcessBuilder将可执行文件及其参数表示为一个列表。该片段没有启动进程或演示shell命令注入。

Correct Usage / 正确用法

This illustrative example starts a process with a modified working directory and passes the executable and each argument separately. Keep the executable and working directory trusted, and validate any untrusted arguments for the invoked program. Argument separation does not replace argument validation.

此示例说明了一个过程,它使用修改后的工作目录启动进程,并分别传递可执行文件和每个参数。保持可执行文件和工作目录受信任,并对调用程序中的任何不受信任的参数进行验证。参数分离不能替代参数验证。

ProcessBuilder pb = new ProcessBuilder("TrustedCmd", "TrustedArg1", "TrustedArg2");
Map<String, String> env = pb.environment();
pb.directory(new File("TrustedDir"));
Process p = pb.start();

Network Protocols / 网络协议

Web applications often communicate with network daemons (like SMTP, IMAP, FTP) where user input becomes part of the communication stream. Here it is possible to inject command sequences to abuse an established session.

Web应用程序通常与网络守护进程(如SMTP、IMAP、FTP)进行通信,用户输入成为通信流的一部分。在这里,可以注入命令序列以滥用已建立的会话。

Injection Prevention Rules / 注入预防规则

Rule #1 (Perform proper input validation) / 规则#1(执行适当的输入验证)

Perform proper input validation. Positive or allowlist input validation with appropriate canonicalization is also recommended, but is not a complete defense as many applications require special characters in their input.

执行适当的输入验证。建议使用正则或允许列表输入验证,并进行适当的规范化,但这不是完整的防御,因为许多应用程序需要在其输入中使用特殊字符。

Rule #2 (Use a safe API) / 规则#2(使用安全的API)

The preferred option is to use a safe API which avoids the use of the interpreter entirely or provides a parameterized interface. Be careful of APIs, such as stored procedures, that are parameterized, but can still introduce injection under the hood.

首选选项是使用安全的API,该API完全避免使用解释器或提供参数化接口。小心使用参数化的API,例如存储过程,这些API可以避免注入,但仍然可能在底层引入注入。

Rule #3 (Contextually escape user data) / 规则#3(上下文转义用户数据)

If a parameterized API is not available, you should carefully escape special characters using the specific escape syntax for that interpreter.

如果不可用参数化API,您应谨慎使用该解释器的特定转义语法来转义特殊字符。

References / 参考