C和C++安全编码(原书第2版)
上QQ阅读APP看书,第一时间看更新

2.6.2 输入验证

缓解缓冲区溢出的最好方式是防止它们。要做到这点需要开发人员来防止字符串或内存拷贝溢出他们的目标缓冲区。可以通过确保输入数据不超过用来存储它的最小的缓冲区的大小来防止缓冲区溢出。例2.15是一个简单的执行输入验证的函数。

例2.15 输入验证


1  void f(const char *arg) {
2   char buff[100];
3   if (strlen(arg) >= sizeof(buff)) {
4     abort();
5   }
6   strcpy(buff, arg);
7   /* ... */
8  }

任何到达某个跨越信任边界的程序接口的数据都需要验证。这类数据的例子包括main()函数的argv和argc参数、环境变量,以及从套接字、管道、文件、信号、共享内存和设备中读取的数据。

虽然这个例子只涉及字符串的长度,但还有许多其他类型的验证可以执行。例如,要被发送到SQL数据库的输入,将需要验证,以检测和防止SQL注入攻击。如果输入最终可能会跳到一个网页,那么它也应该被验证,以防止跨站点脚本(Gross-Site Scripting XSS)攻击。

幸运的是,输入验证适用于所有类别的字符串漏洞,但它需要开发人员正确识别和验证可能会导致缓冲区溢出或其他漏洞的所有外部输入。因为这个过程很容易产生错误,为谨慎起见,这个缓解策略通常需要与其他策略(例如,用更安全的函数替换可疑的函数)结合使用。