【问题标题】:What are the potential security vulnerabilities? C++有哪些潜在的安全漏洞? C++
【发布时间】:2011-08-18 21:46:19
【问题描述】:

我的老板让我查看以下代码并告诉他潜在的安全漏洞是什么。我不太擅长这种事情,因为我不认为试图破解代码。我所看到的是没有任何东西被宣布为私有的,但除此之外我不知道。

#define NAME_SIZE (unsigned char) 255
// user input should contain the user’s name (first name space
// middle initial space last name and a null
// character), and was entered directly by the user.
// Returns the first character in the user input, or -1 if the method failed.
char poor_method(char* user_input, char* first, char *middle, char* last)
{
   char*buffer;
   char length;

   // find first name
   buffer = strtok(user_input, " ");
   if(buffer==0)
   {
        return -1;
   }
   length = strlen(buffer);
   if(length <= NAME_SIZE)
   {
        strcpy(first, buffer);
   }

   // find middle name
   buffer = strtok(NULL, " ");
   if(buffer==0)
   {
        return-1;
   }
   if(middle)
       *middle = buffer[0];

   // find last name
   buffer = strtok(NULL, "\0");
   length = strlen(buffer);
   if(length <= NAME_SIZE)
   {
       strcpy(last, buffer);
   }
   // Check to make sure that all of the user input was used
   buffer = strtok(NULL, "\0");
   if(buffer != NULL)
   {
       return-1;
   }
   return first[0];
}

存在哪些安全漏洞?

【问题讨论】:

  • 扔掉它,用适当的 C++ 方式编写它。对于初学者来说,strtok 不是线程安全的。
  • 我希望你的老板不是这样。 ;) 通过“安全”,您似乎认为它与黑客攻击有关。难道他不能简单地表示记忆问题、输入格式错误等。也许这可能不是你的舒适区?
  • @Bart 也许他知道。当我听到安全性时,我只是假设黑客攻击。我就这样看!
  • strtok,取决于 C 运行时,是线程安全的。
  • 查找Buffer Overflow。你也可以搜索ITsec.SE

标签: c++ security code-access-security


【解决方案1】:

擅长编写安全代码

您很可能想要您负责找到进入bugtraqcve 的方式的系统。如果你不明白,对你的老板诚实。告诉他你不明白,你想努力。拿起Writing Secure Code。读它,学习它,爱它。在 SO 上问这个问题并给你的老板答案从长远来看肯定对​​你没有帮助。

然后再看示例代码:)

【讨论】:

    【解决方案2】:

    我所看到的(绝不是完整的列表):

    1. 无法保证您会获得一个指向以空值结尾的字符串的 char 指针(除非允许您做出这样的假设,而不是真正安全的假设)。
    2. strtok 和 strcpy 是 C 的做事方式,并带有编写 C 代码的乐趣。如果你必须使用它们,就这样吧(只要确保你能保证你对这些函数的输入确实是有效的)。否则,请尝试切换您的代码以使用 std::string 和“C++ 方式”(正如 Cat Plus Plus 所说)
    3. 我假设这是一个错字:

      charpoor_method(
      您在 charpoor_method( 之间缺少一个空格
    4. 您没有检查 firstlast 是否确实是有效的指针(不幸的是,您能做的最好的事情就是对照 NULL 检查它们)。

    5. 无法保证缓冲区 firstlast 确实可以保存您复制给它们的任何内容。
    6. 另一个错字:
    returnfirst[0];

    returnfirst[0] 之间缺少空格

    学习编写安全代码是一件非常重要的事情。听从布莱希特的建议,好好学习。

    【讨论】:

      【解决方案3】:
      1. 好的 strtok 假设 user_input 以 NULL 结尾,这可能不是真的。
      
       charlength = strlen(buffer);
        if(length &lt= NAME_SIZE)
        {
              strcpy(first, buffer);
        }
      
      
      1. 这里的charlenght是未声明的,长度也是,应该声明为unsigned int。

      2. strlen 不会将 '\0' 计为长度的一部分,因此如果缓冲区的 len 为 255 + 1('\0',则稍后 strcpy 会将 '\0' 复制到 First 之后)

      3. 同样未知 char *first 大小是否是,它应该是 NAME_SIZE 但比较应该是 长度

      我可能会重写整个东西,很丑。

      【讨论】:

      • 不应该charlengthsize_t
      • 是的,size_t 是 typedef as unsigned int
      • 来自stackoverflow.com/questions/131803/unsigned-int-vs-size-t "[size_t] 可能比 unsigned int 更大、相等甚至更小,您的编译器可能会出于优化目的对其进行假设。"
      • 这是他给我看的。我假设它只是为了教新员工而写的。
      【解决方案4】:

      而不是使用strcpy(),而是使用带有特定长度参数的strncpy(),因为该函数,如strtok(),假定源的缓冲区以NULL结尾,但情况可能并非如此,给你一个复制到firstlast 指向的缓冲区中的数据的缓冲区溢出。此外,您不知道为firstlast 分配了多长时间的缓冲区......不要假设您的函数的用户已经正确分配了足够的内存来复制,除非他们已经通过了您一个参数告诉您缓冲区中有足够的内存插槽。否则,您可能(并且很可能会)以缓冲区溢出告终。

      此外,如果您使用 C99,您可能希望使用 restrict 关键字,以防止函数的调用者为 bufferfirstlast 的同一内存位置设置别名。

      【讨论】:

        猜你喜欢
        • 2011-04-09
        • 2019-02-08
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 2018-10-07
        • 1970-01-01
        • 1970-01-01
        • 2017-11-24
        相关资源
        最近更新 更多