关于C#:snprintf或vsnprintf是否更好,如何确保安全使用它们?

Is snprintf or vsnprintf better, and how can I ensure I'm using them securely?

我决定在一些旧代码上运行静态分析工具,并且发现了很多使用sprintf的地方。 该工具建议使用vsnprintf或snprintf替换调用,因为sprintf不会对缓冲区溢出进行任何形式的边界检查。

我可以轻松地对调用进行查找和替换,以使其改为使用snprintf或vsnprintf,但我想确保为了确保功能的安全性,无需执行其他任何操作

在某些情况下,所使用的字符串源自用户输入,而在某些情况下则不是。

有人对正确的做法有任何建议吗?


I can easily just do a find and replace on the calls so that it uses snprintf or vsnprintf instead

不,这不是那么容易。 只需查看snprintfvsnprintf的定义,您就会发现它们采用了名为size的额外参数,用于指定输出缓冲区的长度。 这就是函数名称中的n的含义。 为了使代码安全,您必须查看正在执行sprintf的每个位置,找出可以安全写入输出缓冲区的最大字节数,并将该数字作为size参数传递给vsnprintf

不安全的代码:

1
2
char buffer[10];
sprintf(buffer,"%d %d", x, y);  // UNSAFE if x and y can be large

等效安全代码:

1
2
char buffer[10];
snprintf(buffer, sizeof(buffer),"%d %d", x, y);

也许如果您所有的代码都适合上面的示例,那么您可以搜索并替换。 但是对于更复杂的情况,您可能必须考虑一下。