当前位置: 首页 > article >正文

C语言中危险函数

在 C 语言中,有一些函数因为存在缓冲区溢出、格式字符串漏洞等问题,被认为是“危险函数”。这些函数通常不能有效地检查输入的长度或数据,容易导致程序崩溃、内存泄漏或安全漏洞。常见的危险函数有:

1. gets()

gets() 函数用于从标准输入读取字符串,但它没有限制输入的长度。这就导致了缓冲区溢出问题。如果用户输入的字符串超出了缓冲区的大小,程序会覆盖其他内存区域,可能导致未定义行为或攻击者执行恶意代码。

替代函数fgets(),它允许指定读取的最大字符数,从而防止溢出。

2. scanf()

scanf() 在读取用户输入时,如果没有正确指定格式控制符的长度限制,也有可能导致缓冲区溢出。例如,scanf("%s", buffer) 会继续读取直到遇到空白字符,而不检查 buffer 的大小。

替代方法:使用限定输入大小的格式,如 scanf("%99s", buffer),或者使用 fgets() 等安全输入函数。

3. strcpy()strcat()

strcpy()strcat() 分别用于字符串拷贝和连接操作,但它们不会检查目标缓冲区的大小,容易造成缓冲区溢出,尤其是当输入的字符串长度超过目标数组的容量时。

替代函数

  • strncpy():限制拷贝的字符数(但仍需小心,确保目标数组有足够的空间)。
  • strncat():限制连接的字符数。
  • 推荐使用 snprintf()strlcpy()(某些库提供)。

4. sprintf()vsprintf()

printf() 系列的函数在输出到字符数组时,如果没有检查目标数组的大小,也可能导致缓冲区溢出,特别是当格式字符串非常复杂或者输入数据太大时。

替代函数

  • snprintf():可以指定最大输出长度,避免溢出。
  • vsnprintf():用于格式化可变参数的版本。

5. memcpy()memmove()

这两个函数用于内存拷贝操作,但它们不会检查目标缓冲区的大小,使用时很容易引发缓冲区溢出问题。尤其在拷贝的长度不确定时,使用不当会导致内存破坏。

替代方法:如果长度已知,确保不会超过目标缓冲区大小;否则使用带有边界检查的函数,如 memcpy_s()(在某些平台上可用)。

6. strtok()

strtok() 用于字符串分割,但它会直接修改原始字符串,并返回指向分割后的子字符串的指针。这种操作可能破坏原始数据,也容易出现内存泄漏或访问非法内存。

替代方法:使用 strtok_r(),它是线程安全的。

7. alloca()

alloca() 函数分配内存,并且分配的内存是在栈上,而不是堆上。虽然它的作用和 malloc() 类似,但因为栈空间有限,使用不当可能会导致栈溢出。此外,它没有 free() 函数释放内存,导致内存泄漏。

替代方法:尽量避免使用 alloca(),可以使用 malloc() 配合 free() 来管理堆内存。

8. system()

system() 函数用于执行系统命令,它会把字符串传递给操作系统的命令行解释器。在接受用户输入时,恶意用户可能通过构造特定的命令,执行系统命令,从而导致安全漏洞。

替代方法:避免直接使用 system(),可以使用更安全的替代方法,如 exec() 系列函数,或者通过更安全的方式调用外部程序。

9. vprintf()vfprintf()

这些函数用于格式化输出,但如果格式化字符串不可靠(比如由用户提供),可能会导致格式字符串攻击。例如,攻击者通过控制格式字符串,可以导致程序泄露内存内容或执行任意代码。

替代方法:使用参数校验,确保格式字符串是固定的,或者使用 snprintf() 等安全函数。

10. longjmp()setjmp()

setjmp()longjmp() 用于在程序中实现非局部跳转(类似异常处理机制)。虽然它们本身并不直接导致缓冲区溢出或内存泄漏,但它们的使用可能会绕过正常的资源清理流程(如栈上的变量销毁),因此,如果使用不当,可能会导致资源泄露或程序状态不一致。

建议:尽量避免在代码中滥用 setjmp()longjmp(),并确保它们仅用于明确的控制流,避免跳过栈帧中重要的资源释放操作。

11. rand()srand()

虽然 rand()srand() 本身不会引发安全漏洞,但它们的伪随机性较差,生成的随机数序列很容易被预测。在密码学相关应用中,使用 rand() 生成的随机数不适合用于加密或安全相关的操作,因为它们不够随机,容易被攻击者预测。

替代方法:对于安全敏感的应用,应该使用更为安全的随机数生成方法,例如 random()arc4random(),或者在现代系统中使用 openssl 库提供的高质量随机数生成函数。

12. tmpnam()tempnam()

tmpnam()tempnam() 用于生成临时文件名,但它们有可能导致竞争条件(TOCTOU,时间一环条件)漏洞。尤其是在多线程环境或多个进程并发执行时,可能会导致文件被其他进程提前创建,从而被攻击者利用。

替代方法:使用更安全的 mkstemp()tmpfile(),这些函数会创建并返回一个临时文件,并且具备更好的安全性。

13. strchr()strrchr()

strchr()strrchr() 分别用于查找字符串中第一次和最后一次出现指定字符的位置。它们本身不是不安全的,但如果传入一个没有 \0 结尾的字符串,可能会导致越界访问。由于 C 语言字符串是基于空字符终止的,错误的字符串输入可能导致无法预料的行为。

建议:确保传入给 strchr()strrchr() 的字符串是合法的以避免访问非法内存。

14. setvbuf()setbuf()

setvbuf()setbuf() 用于设置文件流的缓冲区大小和类型,但如果不小心使用,可能会导致缓冲区溢出或错误的缓冲区处理。例如,如果你没有足够的内存或缓冲区空间,可能会出现崩溃或资源泄漏。

建议:使用时小心指定合适的缓冲区大小,确保程序稳定。

15. sscanf()

sscanf() 是一种从字符串中读取格式化数据的函数,虽然它功能强大,但也很容易出错。没有正确限制输入的长度或格式时,sscanf() 可能会导致缓冲区溢出、内存泄漏或其他问题。

建议:使用时确保格式字符串正确,且传入的缓冲区有足够的空间。

16. vfork()

vfork() 用于创建新进程,与 fork() 类似,但它的行为不同,通常会导致父进程被暂停,直到子进程执行完毕。因为 vfork() 可能改变进程的状态,容易引发竞态条件或不一致的资源状态,从而导致难以调试的错误。

建议:在不需要特殊优化的情况下,尽量避免使用 vfork(),改用 fork(),并且确保正确管理资源。

17. strtol()strtoul()

虽然这些函数用于将字符串转换为长整型或无符号长整型,但如果输入字符串不符合预期格式,可能会导致未定义的行为,尤其是在字符串超出整数范围或包含非数字字符时。

建议:使用时确保输入字符串的格式正确,并检查转换后的返回值和错误码。

18. gethostbyname()gethostbyaddr()

这些函数用于 DNS 查询,但它们已经被标记为过时(deprecated),并且存在潜在的安全风险,例如缓冲区溢出,尤其是在一些老旧的代码库中。

替代方法:使用 getaddrinfo(),这是一个更现代、更安全的替代方案。

19. fseek()ftell()

虽然 fseek()ftell() 本身不是危险的函数,但在某些情况下,它们可能会导致对文件指针的错误操作,导致程序崩溃或不一致的文件状态。例如,在文件打开模式不正确时,可能会导致未定义的行为。

总结

以上这些“危险函数”通常是因为缺乏足够的输入验证或边界检查,在处理数据时容易引发缓冲区溢出、格式字符串漏洞等问题。现代编程推荐使用更安全的替代函数,如 fgets()snprintf()strncpy() 等,来确保程序的健壮性和安全性。此外,始终注意进行输入验证,避免直接信任用户输入,减少安全漏洞的风险。


http://www.kler.cn/a/514624.html

相关文章:

  • nslookup在内网渗透的使用
  • Java面试专题——面向对象
  • npm操作大全:从入门到精通
  • 【0x04】HCI_Connection_Request事件详解
  • 代码随想录刷题day13|(链表篇)24.两两交换链表中的结点
  • CentOS 安装Redis
  • JMeter 测试Dubbo 接口
  • Win10系统部署RabbitMQ Server
  • linux系统安装vmware workstation
  • Laravel 请求接口 调用2次
  • TS报错解决:不能将类型“string | null”分配给类型“string | undefined”
  • 2025年最新电子制造行业CRM售后管理解决方案
  • SCSS概念及使用
  • 我的2024:创作历程与成长总结
  • 【0x05】HCI_Disconnection_Complete事件详解
  • GD32L233RB 驱动数码管
  • 从工厂到桌面:3D打印制造潮玩手办
  • [MySQL]MySQL数据库的介绍和库相关操作
  • SimpleFOC STM32教程09|基于STM32F103+CubeMX,ADC采样相电流
  • PAT (Basic Level) Practice 乙级1041-1045
  • 等变即插即用图像重建
  • Windows第一次上手鸿蒙周边
  • 方法建议ChatGPT提示词分享
  • 人工智能的出现,给生命科学领域的研究带来全新的视角|行业前沿·25-01-22
  • 从构思到上线的全栈开发指南:全栈开发中的技术选型和架构
  • Harmonyos之多目标构建产物实践