解决“编写安全代码”中的安全漏洞

时间:2011-06-18 19:25:23

标签: c security

我正在研究代码安全性,我正在尝试对以下2个片段进行安全性分析,取自“编写安全代码”,第2版:

http://www.di.uniba.it/~ndm/corsi/sa/materiale/lab/StackOverrun.c

http://www.di.uniba.it/~ndm/corsi/sa/materiale/lab/FormatString.c

在第一个中我认为唯一不安全的陈述是     strcpy(buf, input); 应该是     strncpy(buf, input, sizeof(buf-1)); 所有其他printf都是安全的:即使他们使用的参数少于他们的意思,他们也是故意这样做的。

在第二个printf中,fprintf(stdout, buf);是安全的,但fprintf(stdout, "%s", buf);不是,应该替换为此代码:pFile = fopen(argv[1], "r");

我的问题是由于可能的竞争条件,{{1}}也被分析程序认为是不安全的,但我认为在此代码中无法利用它。如果文件以只读方式打开,攻击者可以用它做一些讨厌的事吗?我想不。

所以问题是:你认为这种分析是否正确?你能找到其他瑕疵还是我的推理?

谢谢!

2 个答案:

答案 0 :(得分:0)

我的第一个想法是将非清理程序输入传递给libc调用是不好的。有太多的情况会导致libc溢出,开发人员不应该传递超出libc期望的参数(在这种情况下,字符串应该是< PATH_MAX)。

但是既然你提到了竞争条件,我认为虽然在这个特定的例子中没有特别的问题,但是fopen()的使用总体上是不受欢迎的,因为它很容易出现竞争条件。如果要使用文件名而不是文件句柄的函数来寻址文件,任何文件。如果通过路径名称引用文件,使用一个操作或另一个操作,则文件的状态可能会发生变化,程序对该状态的假设可能不再正确。在下面的文章中有更好的解释。

http://www.sans.edu/research/security-laboratory/article/race-cndtns

http://www.unixprogramming.info/s_isregfile-race-conditions

答案 1 :(得分:0)

来自Apple Development site这个明确的描述:

如果您打开一个文件然后从中读取,即使您的应用程序在这两个操作之间没有执行任何其他操作,其他一些进程也可能会在文件打开之后和读取之前更改该文件。如果两个不同的进程(在相同或不同的应用程序中)写入同一个文件,则无法知道哪个进程将先写入,哪个将覆盖另一个进程写入的数据。这种情况会导致安全漏洞。

可以利用两种基本类型的竞争条件:使用检查时间(TOCTOU)和信号处理。

此外,如所示的fopen()调用没有对文件名进行任何清理。当然你不会那样做,对吧?这个名字绝对应该被分析,检查并且根本不被信任,因为它是该程序的一个参数。理想情况下,您应该use more than a single attribute to identify a file