了解 sprintf(...) 的危险

2024-02-14

OWASP http://www.owasp.org/index.php/Buffer_Overruns_and_Overflows says:

“C 库函数,例如 strcpy ()、strcat()、sprintf() 和 vsprintf () 对以 null 结尾的字符串进行操作 并且不执行边界检查。”

sprintf http://en.cppreference.com/w/cpp/io/c/fprintf将格式化数据写入字符串 int sprintf ( char * str, const char * format, ... );

Example:

sprintf(str, "%s", message); // assume declaration and 
                             // initialization of variables

如果我理解 OWASP 的评论,那么使用 sprintf 的危险是

1) if message的长度 >str的长度,存在缓冲区溢出

and

2) if message不以空终止\0, then message可以被复制到str超出内存地址message,导致缓冲区溢出

请确认/否认。谢谢


您在这两个问题上都是正确的,尽管它们实际上都是同一个问题(即访问超出数组边界的数据)。

解决第一个问题的方法是使用std::snprintf https://en.cppreference.com/w/cpp/io/c/fprintf,它接受缓冲区大小作为参数。

第二个问题的解决方案是给出最大长度参数snprintf。例如:

char buffer[128];

std::snprintf(buffer, sizeof(buffer), "This is a %.4s\n", "testGARBAGE DATA");

// std::strcmp(buffer, "This is a test\n") == 0

如果你想存储整个字符串(例如在这种情况下sizeof(buffer)太小),运行snprintf twice:

int length = std::snprintf(nullptr, 0, "This is a %.4s\n", "testGARBAGE DATA");

++length;           // +1 for null terminator
char *buffer = new char[length];

std::snprintf(buffer, length, "This is a %.4s\n", "testGARBAGE DATA");

(您可能可以使用以下方法将其放入函数中va或可变参数模板。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 sprintf(...) 的危险 的相关文章

随机推荐