尽可能安全地用c语言打开一个文件。

问题描述 投票:4回答:4

我将写一个程序如下

int main ()
{
      FILE *fp = fopen("test.txt", "r")

      if (fp == NULL)
      {
           printf("Sorry, file doesn't exist.");
           return 0;     
      }

   return 0;
} 

在打开文件之前或之后,有什么其他需要确认的检查吗?

如果打开文件会损坏系统(病毒),有什么检查方法吗?

如果文件不是一个.txt文件,用户只是把mp3文件改名为txt文件,怎么办?

c file error-handling fopen
4个回答
3
投票

不需要其他检查。

我也总是在实践中调用 fclose然而,当完成FILE*。


2
投票

模式 r 应仅用于打开文本文件。不同的系统有不同的文本存储方式,这种模式会自动对文件进行相应的翻译。例如,DOSWindows使用 \r\n 来表示新行,类UNIX系统使用 \n,MAC使用 \r 在其他可能的差异中。

要想真正如实地打开和读取一个文件,在 二进制安全模式,你应该使用 rb.

这种模式可以让你完全控制你要写到二进制级别的东西,是唯一安全的读写二进制数据的方式,如 struct 转储、加密信息等。


1
投票

打开文件后

正如你在打开文件时的小心翼翼一样,你在读写和关闭文件时也应该如此。所以一定要检查涉及到的调用结果才行。


0
投票

我看这是个老问题。不过。

你可以做一些额外的安全检查 来验证你打开的是一个真正的文件,而不是一个符号链接。

原因:用指向另一个文件的链接替换文件是已知的攻击技术之一(与CWE-362有关).文件可以被指向一个包含序列的工程文件的链接替换,该序列应该黑客崩溃你的应用程序,而不是预期的文件。

所以,最好的做法是添加这样的代码。

   #include <sys/types.h>
   #include <sys/stat.h>
   #include <unistd.h>

    /* Return: 0 if file is a regular file, -1 if not */
    static int test_file_type(const char *file)
    {
        struct stat st;

        if (0 != lstat(file, &st)) {
            fprintf(stderr, "lstat failed, probably no such a file\n");
            perror("lstat");
            return (-1);
        }

        if (S_IFREG != (st.st_mode & S_IFMT)) {
            fprintf(stderr, "Error on file [%s] opening: not a regular file, but ", file);
            switch (st.st_mode & S_IFMT) {
            case S_IFSOCK:
                fprintf(stderr, "socket\n");
                break;
            case S_IFLNK:
                fprintf(stderr, "symbolic link\n");
                break;
            case S_IFBLK:
                fprintf(stderr, "block device\n");
                break;
            case S_IFDIR:
                fprintf(stderr, "directory\n");
                break;
            case S_IFCHR:
                fprintf(stderr, "character device\n");
                break;
            case S_IFIFO:
                fprintf(stderr, "FIFO\n");
                break;
            }
            return (-1);
        }
        return (0);
    }

如果这个函数返回< 0, 这个文件就不是一个常规文件. 不要打开它。

另外,请阅读 此处

© www.soinside.com 2019 - 2024. All rights reserved.