⽂件参数Shell命令注⼊(Appscan)
常规
有多种减轻威胁的技巧:
[1] 如果可能,使⽤库调⽤⽽不是外部进程来重新创建所需功能。
[2] 策略:沙箱或监狱
在进程和操作系统之间强制实施严格边界的“监狱”或类似沙箱环境中运⾏代码。这可以有效限制您的软件可访问特定⽬录中的哪些⽂件或者可以执⾏哪些命令。操作系统级别的⽰例包括 Unix chroot jail、AppArmor 和 SELinux。通常,受管代码可提供⼀定的保护。例
如,Java SecurityManager 中的 java.io.FilePermission 允许您指定针对⽂件操作的限制。但是,此解决⽅案可能很难实施,并且它仅限制了对操作系统的影响;您的应⽤程序的其余部分仍有可能受到损害。请注意避免 CWE-243 以及与监狱相关的其他弱点。
[3] 策略:库或框架
使⽤禁⽌此弱点出现的经过审核的库或框架,或⾄少提供更容易避免此弱点的构造。
例如,考虑使⽤ ESAPI 编码控件
或类似的⼯具、库或框架。这些有助于对输出编码。
[4] 策略:输⼊验证
假定所有输⼊都是恶意的。使⽤“接受已知善意”输⼊验证策略,即使⽤严格遵守规范的可接受输⼊的⽩名单。拒绝没有严格遵守规范的任何输⼊,或者将其变换为严格遵守规范的内容。不要专门依赖于查恶意或格式错误的输⼊(即,不依赖于⿊名单)。但是,⿊名单可帮助检测潜在攻击,或者确定哪些输⼊由于格式严重错误⽽应直接拒绝。执⾏输⼊验证时,请考虑所有潜在相关的属性,包括长度、输⼊类型、可接受的值的完整范围、缺少或多余的输⼊、语法、在相关字段之间是否⼀致以及是否遵守了业务规则。作为业务规则逻辑的⽰
例,“boat”可能在语法上有效(因为它仅包含字母数字字符),但如果预期为颜⾊(如“red”或“blue”),那么它就⽆效。构造操作系统命令字符串时,请使⽤严格的⽩名单以根据请求中参数的预期值来限制字符集。这将间接限制攻击的范围,但是此技巧的重要性不及适当的输出编码和转义。
请注意,适当的输出编码、转义和引⽤是防⽌操作系统命令注⼊的最有效解决⽅案,虽然输⼊验证可
能会提供⼀定的深度防御。这是因为它会有效限制将在输出中出现的内容。输⼊验证并不总是能够防⽌操作系统命令注⼊,尤其是在您需要⽀持可包含任意字符的⾃由格式⽂本字段的情况下。例如,调⽤邮件程序时,您可能需要允许主题字段包含在其他情况下很危险的输⼊(如“;”和“>”字符),这些输⼊需要转义或以其他⽅式进⾏处理。在此情况下,除去该字符可能会降低操作系统命令注⼊的风险,但是这会产⽣不正确的⾏为,因为这样就不会按照⽤户的需要来记录主题字段。这可能看起来只是略有不便,但在程序依赖于结构良好的主题⾏以便向其他组件传递消息时,这种情况就更为重要。
这可能看起来只是略有不便,但在需要表⽰不等式的数学论坛中,这种情况就更为重要。即使在验证中出错(例如,在 100 个输⼊字段中忘记⼀个字段),相应的编码仍有可能针对基于注⼊的攻击为您提供防护。只要输⼊验证不是孤⽴完成的,便仍是有⽤的技巧,因为它可以⼤⼤减少攻击出现的机会,使您能够检测某些攻击,并提供正确编码所⽆法解决的其他安全性优势。[5] 策略:环境固化
使⽤完成必要任务所需的最低特权来运⾏代码。
. 如果可能,请使⽤仅⽤于单个任务的有限特权来创建孤⽴的帐户。这样,即使攻击成功,攻击者也⽆法⽴即访问软件或其环境的其余部分。例如,数据库应⽤程序很少需要以数据库管理员⾝份运⾏,特别是在⽇常操作中。
Asp.Net
ASP.NET 提供多种⽅法来在打开⽂件之前对⽂件名进⾏验证。例如:[1] Server.MapPath() ⽅法:该⽅法接收路径(字符串),并将指定的相对或虚拟路径映射到服务器上对应的物理⽬录。
parameter数据类型注意:AspEnableParentPaths 属性(Metabase 属性)的缺省值为 FALSE,以确保脚本将不具有对应⽤程序根⽬录以外的⽂件的访问权。将属性值更改为 TRUE 会构成潜在的安全风险。
[2] Path.GetFileName() ⽅法:该⽅法有效除去给定⽂件路径的最后⼀个元素,同时会返回由⽂件路径中直到(但不包括)最后⼀个分隔符字符的所有字符组成的字符串。
注意:如果该⽅法的参数包含诸如以下类型的“InvalidPathChars”,那么“ArgumentException”将会提⾼:
a. 引号(")
b. ⼩于(<)
c. ⼤于(>)
d. 竖线(|)
e. 退格(\b)
f. 空值(\0)
g. Unicode 字符 16 ⾄ 18、20 ⾄ 25。
出于安全考虑,我们建议在对⽂件名进⾏任何输⼊验证前使⽤ Server.MapPath() ⽅法。
J2EE
** ⽂件路径验证:
有多种从“Servlet 容器”访问⽂件系统的⽅法。然⽽,由于这些⽅法中的⼀部分⽀持对 web 根以外的⽂件进⾏访问,所以很危险。有两种安全的 Servlet API ⽅法可访问在服务器的⽂档树中给定其虚拟路径的 web 资源。有两种安全的 Servlet API ⽅法可访问在服务器的⽂档树中给定其虚拟路径的 web 资源。当给定的⽂件名解析为 web 根以外的值时,这些 API 会返回空值。以下 API 应⽤于访问存储在 web 根下的配置⽂件或其他⽂件:
[1] Resource(或 ResourceAsStream)
[2] RealPath
[1] Resource(或 ResourceAsStream)
装⼊ Servlet 配置⽂件(名称为 l,且驻留于应⽤程序的 WEB-INF ⽬录中)的⽰例:
// Example to load the /l configuration file
URL url = getServletContext().getResource("/l");
// Acquire an input stream to the config resource
InputStream configInput = url.openStream();
...
还可以使⽤ ResourceAsStream ⽅法直接获取配置⽂件的输⼊流,如以下⽰例所⽰:
// Example to acquire an input stream to a resource
InputStream configInput = getServletContext().getResourceAsStream("/l");
...
[2] RealPath
该⽅法返回给定其虚拟路径(相对于服务器的 web 根⽽⾔)的资源的真实路径。返回的真实路径格式将适合于 Servlet 容器所运⾏的计算机和操作系统,包括适当的路径分隔符。
该⽅法不如 Resource(或 ResourceAsStream)常⽤,因为它不允许访问未存储在本地⽂件中的资源。如果 Servlet 容器因为任何原因(例如,当内容从 .war 归档中可⽤时)⽆法将虚拟路径转换为真实路径,那么它会返回空值。
该⽅法返回给定其虚拟路径(相对于服务器的 web 根⽽⾔)的资源的真实路径。 该⽅法可能没有在所有 Servlet 引擎中⼀致或正确实现。始终验证返回的路径,如以下⽰例所⽰:
// Example to access a resource RealPath
// Get the virtual path parameter from the http request
String virtualPath = Parameter("virtual_path");
String realPath = getServletContext().getRealPath(virtualPath);
if (realPath != null) {
// verify that realPath is valid
File file = new File(realPath);
if (!ists()) {
// oops, invalid file path
...
}
}
推荐使⽤的 JAVA ⼯具
不适⽤。
参考资料
** 输⼊数据验证:** 输⼊数据验证:虽然为⽅便⽤户⽽在客户端层上提供数据验证,但仍必须使⽤ Servlet 在服务器层上执⾏数据验证。客户端验证本⾝就不安全,因为这些验证可轻易绕过,例如,通过禁⽤ Javascript。
⼀份好的设计通常需要 Web 应⽤程序框架,以提供服务器端实⽤程序例程,从⽽验证以下内容:
[1] 必需字段
[2] 字段数据类型(缺省情况下,所有 HTTP 请求参数都是“字符串”)
[3] 字段长度
[4] 字段范围
[5] 字段选项
[6] 字段模式
[7] cookie 值
[8] HTTP 响应好的做法是将以上例程作为“验证器”实⽤程序类中的静态⽅法实现。以下部分描述验证器类的⼀个⽰例。
[1] 必需字段“始终”检查字段不为空,并且其长度要⼤于零,不包括⾏距和后⾯的空格。如何验证必需字段的⽰例:
// Java example to validate required fields
public Class Validator {
...
public static boolean validateRequired(String value) {
boolean isFieldValid = false;
if (value != null && im().length() > 0) {
isFieldValid = true;
}
return isFieldValid;
}
...
}
...
String fieldValue = Parameter("fieldName");
if (Validator.validateRequired(fieldValue)) {
// fieldValue is valid, continue processing request
.
..
}
[2] 输⼊的 Web 应⽤程序中的字段数据类型和输⼊参数⽋佳。例如,所有 HTTP 请求参数或 cookie 值的类型都是“字符串”。开发者负责验证输⼊的数据类型是否正确。使⽤ Java 基本包装程序类,来检查是否可将字段值安全地转换为所需的基本数据类型。
验证数字字段(int 类型)的⽅式的⽰例:
// Java example to validate that a field is an int number
public Class Validator {
...
public static boolean validateInt(String value) {
boolean isFieldValid = false;
try {
Integer.parseInt(value);
isFieldValid = true;
} catch (Exception e) {
isFieldValid = false;
}
return isFieldValid;
}
...
}
...
// check if the HTTP request parameter is of type int
String fieldValue = Parameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// fieldValue is valid, continue processing request
...
}
好的做法是将所有 HTTP 请求参数转换为其各⾃的数据类型。例如,将请求参数的“integerValue”存储在请求属性中,并按以下⽰例所⽰来使⽤:
// Example to convert the HTTP request parameter to a primitive wrapper data type
// and store this value in a request attribute for further processing
String fieldValue = Parameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// convert fieldValue to an Integer
Integer integerValue = Integer(fieldValue);
// store integerValue in a request attribute
request.setAttribute("fieldName", integerValue);
}
...
// Use the request attribute for further processing
Integer integerValue = (Attribute("fieldName");
...
应⽤程序应处理的主要 Java 数据类型:
- Byte
- Short
-
Integer
- Long
- Float
- Double
- Date
[3] 字段长度“始终”确保输⼊参数(HTTP 请求参数或 cookie 值)有最⼩长度和/或最⼤长度的限制。以下⽰例验证 userName 字段的长度是否在 8 ⾄ 20 个字符之间:
// Example to validate the field length
public Class Validator {
...
public static boolean validateLength(String value, int minLength, int maxLength) {
String validatedValue = value;
if (!validateRequired(value)) {
validatedValue = "";
}
return (validatedValue.length() >= minLength &&
validatedValue.length() <= maxLength);
}
...
}
...
String userName = Parameter("userName");
if (Validator.validateRequired(userName)) {
if (Validator.validateLength(userName, 8, 20)) {
// userName is valid, continue further processing
...
}
}
[4] 字段范围
始终确保输⼊参数是在由功能需求定义的范围内。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。