C 安全函数
                           
天天向上
发布: 2025-04-06 00:12:53

原创
673 人浏览过

在 C 语言中,由于其对内存的低级操作能力,安全问题(如缓冲区溢出、未定义行为、格式字符串漏洞等)非常常见。为了提高程序的健壮性和安全性,建议使用安全函数(safe functions)代替传统的“危险函数”。


1. 什么是 C 安全函数?

C 安全函数是在调用时显式限制内存访问范围避免缓冲区溢出格式化漏洞等问题的函数。这些函数主要是对传统标准库函数(如 strcpy, sprintf, gets)的安全替代。

常见安全函数标准包括:

  • C11 标准 Annex K(可选)
  • POSIX 安全扩展
  • 微软 C 运行库扩展(如 strcpy_s, sprintf_s

2. 常见危险函数与安全替代

危险函数问题推荐安全替代说明
gets()无法限制输入长度,极易溢出fgets()stdin 读取但限制长度
strcpy()不检查目标缓冲区大小strncpy() / strcpy_s()限制复制的最大字符数
strcat()同上strncat() / strcat_s()附加前确保不溢出
sprintf()格式化不安全snprintf() / sprintf_s()限制输出长度
scanf("%s", ...)不限制输入长度scanf("%Ns", ...) / fgets()N 为最大长度
memcpy()容易写越界memmove_s()带有边界检查(需平台支持)

3. 安全函数示例(推荐写法)

✅ 使用 fgets() 代替 gets()

#include <stdio.h>

int main() {
    char buffer[100];
    printf("请输入字符串:");
    fgets(buffer, sizeof(buffer), stdin); // 限制最大读取长度
    printf("你输入的是:%s", buffer);
    return 0;
}

✅ 使用 strncpy() 代替 strcpy()

#include <string.h>

char dest[20];
strncpy(dest, "Hello, World!", sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 确保以 null 结尾

✅ 使用 snprintf() 代替 sprintf()

#include <stdio.h>

char buffer[50];
snprintf(buffer, sizeof(buffer), "Value is: %d", 42);

4. 权威参考链接

内容链接
C11 安全函数标准(Annex K)https://en.cppreference.com/w/c/string/byte
Microsoft 安全函数文档https://learn.microsoft.com/en-us/cpp/c-runtime-library/security-features-in-the-crt
GNU fgets 函数文档https://man7.org/linux/man-pages/man3/fgets.3.html
CERT C 安全编码标准https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard

5. 实战建议

  • 总是限制内存访问长度,哪怕你确定不会溢出;
  • 使用现代编译器开启警告和静态检查(如 -Wall -Wextra -fsanitize=address);
  • 如果在 嵌入式环境或跨平台项目中,无法使用 *_s() 系列函数,可以用 strncpy, snprintf 等,并配合断言或边界检查;
  • 避免自己写字符串操作函数,除非你完全了解底层实现;
发表回复 0

Your email address will not be published. Required fields are marked *