ID: 476 类型:基础 | 状态:草稿 |
描述
空指针间接引用发生在应用程序间接引用其预期有效但实际为空的指针时,通常会导致崩溃或退出。
扩展描述
空指针间接引用可能在多个弱点发生后发生,如竞争条件和简单程序省略等。
相关视图
与“研究层面”视图(CWE-1000)相关
与“开发层面”视图(CWE-699)相关
引入模式
阶段 | 说明 |
实现 |
应用平台
语言
C (出现的可能性不确定)
C++ (出现的可能性不确定)
Java (出现的可能性不确定)
C# (出现的可能性不确定)
后果
范围 | 冲击 | 可能性 |
可用性 | 技术冲击: DoS: 崩溃、退出或重启 除非异常处理(在某些平台上)可用并实现,否则空指针间接引用通常会导致流程失败。即使在使用异常处理时,仍然很难将软件恢复到安全操作状态。 | |
完整性 | 技术冲击: 执行未获授权的代码或命令 在非常罕见的情况和环境中,代码执行是可能的。 |
被利用的可能性:
中等
示例
例1
虽然除了认真的编程之外没有完整的修复,但以下步骤将很长一段时间确保不会发生空指针取消引用。
(正确代码)
if (pointer1 != NULL) {
/* make use of pointer1 */
/* ... */
}
如果您使用的是多线程或异步环境,请确保在if语句之前使用适当的锁定API进行锁定,并在完成后解锁。
例2
此示例从用户获取IP地址,验证其格式是否正确,然后查找主机名并将其复制到缓冲区中。
(问题代码)
Example Language: C
void host_lookup(char *user_supplied_addr){
struct hostent *hp;
in_addr_t *addr;
char hostname[64];
in_addr_t inet_addr(const char *cp);
/*routine that ensures user_supplied_addr is in the right format for conversion */
validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr( addr, sizeof(struct in_addr), AF_INET);
strcpy(hostname, hp->h_name);
}
如果攻击者提供的地址格式似乎正确,但该地址无法解析为主机名,则对gethostbyaddr()的调用将返回空值。由于代码没有检查gethostbyddr(cwe-252)的返回值,因此在对strcpy()的调用中将发生空指针间接引用。
注意,这个示例也容易受到缓冲区溢出的攻击(详见 CWE-119).
例3
在下面的代码中,程序员假定系统总是定义了一个名为“cmd”的属性。如果攻击者可以控制程序的环境,从而不定义“cmd”,则程序在尝试调用trim()方法时会抛出空指针异常。
(问题代码)
Example Language: Java
String cmd = System.getProperty("cmd");
cmd = cmd.trim();
例4
此应用程序已注册以在发送意图时处理URL:
(问题代码)
Example Language: Java
...
IntentFilter filter = new IntentFilter("com.example.URLHandler.openURL");
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver, filter);
...
public class UrlHandlerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if("com.example.URLHandler.openURL".equals(intent.getAction())) {
String URL = intent.getStringExtra("URLToOpen");
int length = URL.length();
...
}
}
}
应用程序假定URL将始终包含在意图中。当URL不存在时,对getStringExtra()的调用将返回空值,因此在调用length()时会导致空指针异常。
应对措施
阶段: 实现 如果可以修改的所有指针在使用前都进行了健全性检查,那么几乎可以防止所有空指针取消引用。 |
阶段: 需求 可以选择使用不易受这些问题影响的语言。 |
阶段: 实现 检查返回值的所有函数的结果,并在对其执行操作之前验证该值是否为非空。 有效性: 中等 说明: 检查函数的返回值通常是足够的,但是要注意并发环境中的竞争条件(CWE-362)。此解决方案不处理不正确初始化变量(CWE-665)的使用。 |
阶段: 架构与设计 标识从外部源接收信息的所有变量和数据存储,并应用输入验证以确保它们仅初始化为预期值。 |
阶段: 实现 在声明期间或第一次使用之前,显式初始化所有变量和其他数据存储。 |
阶段: 测试 使用针对这类弱点的自动化静态分析工具。许多现代技术使用数据流分析来最小化误报的数量。这不是一个完美的解决方案,因为100%的准确度和覆盖范围是不可行的。 |
种属
关系 | 类型 | ID | 名称 |
属于 | 398 | ||
属于 | 398 | ||
属于 | 730 | ||
属于 | 737 | CERT C Secure Coding Standard (2008) Chapter 4 - Expressions (EXP) | |
属于 | 742 | CERT C Secure Coding Standard (2008) Chapter 9 - Memory Management (MEM) | |
属于 | 808 | ||
属于 | 867 | ||
属于 | 871 | ||
属于 | 876 | ||
属于 | 884 | ||
属于 | 971 | ||
属于 | 1136 | SEI CERT Oracle Secure Coding Standard for Java - Guidelines 02. Expressions (EXP) | |
属于 | 1157 | SEI CERT C Coding Standard - Guidelines 03. Expressions (EXP) |