snprintf - 安全风险

时间:2013-04-16 09:33:09

标签: c linux security posix printf

unwindmy previous question的回答引发了我另一个问题。我曾经问过关于

的问题
const char *INTERFACE        = "wlan0";
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE);

unwind回复为

  

值得警告,因为它可能存在安全风险,如果字符串参数在运行时是可变的,那么%可能会“悄悄进入”,这将导致问题。因此,如果格式化字符串被硬编码为“做你想做的事”,那就更好了。

我想知道如何更改运行时的字符串参数?

编辑:更清楚一点,任何人都可以举例说明如何更改运行时的字符串参数吗?

1 个答案:

答案 0 :(得分:3)

unwind毫无疑问是指INTERFACE变量。

如果由于某种原因你问用户他们应该使用哪个界面(使用fscanf()之类的东西进入可写缓冲区)并且他们输入"wlan0 %s",那么所有地狱都可能因为你拥有了你有效执行的情况:

snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "wlan0 %s");

在您的格式字符串中使用与<{1}}对应的 no 额外参数。

防止这种情况的方法是使用:

%s

所以篡改snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", INTERFACE); 的人除了改变INTERFACE中的内容之外,对该陈述没有任何影响。

在您的特定情况下:

ifr.ifr_name

你仍然可以完全控制#include <stdio.h> #include <net/if.h> #include <string.h> int main(int argc,char *argv[]){ const char *INTERFACE = "wlan0"; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE); return 0; } 所以没有危险,但是编译器没有进行那种级别的分析 - 它只知道非文字格式字符串是一种风险。