Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 防止删除一组文件的例程具有破坏性_C - Fatal编程技术网

C 防止删除一组文件的例程具有破坏性

C 防止删除一组文件的例程具有破坏性,c,C,下面是我写的一个程序的一个小摘录。该例程通过filenamelist(权限0600),其中包含一个以行分隔的文件名列表,这些文件名存储在目录中(如FileOne\nAnotherFile\nThird file\n),文件扩展名为扩展名。文件名列表来自我程序的另一部分 我有点担心文件名列表会被滥用来删除系统上的其他文件。有没有更好的方法锁定它?最初我存储了要删除的文件的完整路径,但后来分离并硬编码了目录和文件扩展名,试图混淆它 我可能有点偏执,但恶意用户(!)可能会以某种方式用其他文件路径毒害文

下面是我写的一个程序的一个小摘录。该例程通过
filenamelist
(权限0600),其中包含一个以行分隔的文件名列表,这些文件名存储在
目录中(如
FileOne\nAnotherFile\nThird file\n
),文件扩展名为
扩展名。文件名列表来自我程序的另一部分

我有点担心
文件名列表
会被滥用来删除系统上的其他文件。有没有更好的方法锁定它?最初我存储了要删除的文件的完整路径,但后来分离并硬编码了目录和文件扩展名,试图混淆它

我可能有点偏执,但恶意用户(!)可能会以某种方式用其他文件路径毒害
文件名列表。例如,
。/../另一个目录/donotdeleteme.sys
,或者以我想都想不到的方式将其转义

那么,下面的删除例程是否会被误用来删除
目录
之外的文件?关于如何进一步锁定它以防止猫·阿童木有什么建议吗

PS:程序必须以root用户身份运行,因为其操作的一部分是修改用户主目录以外的文件

#define EXTENSION ".stuff"
char *directory = calloc( 28 );
directory = "/usr/local/share/stuffings/";
char *filenamelist = calloc( 24 );
filenamelist = "/etc/stuffing/files.lst";

void delete_files( char* filenamelist, char* directory ) {

  if ( access( filenamelist, F_OK | R_OK ) == 0 ) {
    FILE *filenamelist_fp = fopen( filenamelist, "r" );
    char filename[200];

    while( fgets( filename, 200, filenamelist_fp ) != NULL ) {
      char *pos;
      char *path = calloc( ( strlen( directory ) + strlen( filename ) + strlen( EXTENSION ) + 1 ), sizeof( char ) );

      if ( ( pos=strchr( filename, '\n' ) ) != NULL )
       *pos = '\0';

      strcat( path, directory );
      strcat( path, filename );
      strcat( path, EXTENSION );

      if ( access( path, F_OK | W_OK ) == 0 )
        unlink( path );
      free( path );
    }

    fclose( filenamelist_fp );
    unlink( filenamelist );
  }
} /* © */

如果您添加检查以确保文件名中没有嵌入
/
字符,那么您将完全安全地避免删除给定目录之外的文件(假设使用POSIX平台)。不幸的是,这也会阻止删除给定目录下子目录中的文件。如果这是确定的,那么您可以使用该解决方案

如果您需要支持删除给定目录子目录中的文件,那么第一步是阻止
显示为路径名的任何组件,但这还不够:您需要注意指向给定目录下任何目录的符号链接,因为遵循它们可能会导致删除树外的文件。在这种情况下,最可靠的解决方案可能是自己解析路径名的每个组件,使用
openat
手动打开每个目录组件(在事后比较
fstat
lstat
的结果,以确保没有遵循符号链接),并在末尾使用
unlinkat
删除文件


顺便说一句,您对
访问(filenamelist,F|u OK | R_OK)
的调用是多余和不必要的。在打开文件之前测试对文件的访问没有意义。您最好只使用
fopen()
文件。

如果您添加一个检查以确保文件名中没有嵌入
/
字符,那么您将完全安全地避免删除给定目录之外的文件(假设是POSIX平台)。不幸的是,这也会阻止删除给定目录下子目录中的文件。如果这是确定的,那么您可以使用该解决方案

如果您需要支持删除给定目录子目录中的文件,那么第一步是阻止
显示为路径名的任何组件,但这还不够:您需要注意指向给定目录下任何目录的符号链接,因为遵循它们可能会导致删除树外的文件。在这种情况下,最可靠的解决方案可能是自己解析路径名的每个组件,使用
openat
手动打开每个目录组件(在事后比较
fstat
lstat
的结果,以确保没有遵循符号链接),并在末尾使用
unlinkat
删除文件


顺便说一句,您对
访问(filenamelist,F|u OK | R_OK)
的调用是多余和不必要的。在打开文件之前测试对文件的访问没有意义。您也可以只使用
fopen()
文件。

filenamelist=“/etc/pitching/files.lst”
丢失了您
calloc
之前删除该行的内存句柄。您的意思可能是类似于strcpy(filenamelist,/etc/…)。请注意,在unix中,“\n”是文件名中的有效字符。另外:您可以记住大小并使用snprintf()而不是strcat()。而且access()是没有用的,IMHO。并且:要取消文件链接,您必须具有对该目录的写访问权限,而不必检查该目录。Daniel对dirname也是这么说的,永远不要在默默无闻的情况下尝试安全。这是一个几乎不起作用的坏主意。相反,执行沙箱、加密等经验证的操作。假设“填充”包含由同一用户创建的文件,则允许此程序仅删除用户拥有的文件。
filenamelist=“/etc/pitching/files.lst”
丢失了您
calloc
之前删除该行的内存句柄。您的意思可能是类似于strcpy(filenamelist,/etc/…)。请注意,在unix中,“\n”是文件名中的有效字符。另外:您可以记住大小并使用snprintf()而不是strcat()。而且access()是没有用的,IMHO。并且:要取消文件链接,您必须具有对该目录的写访问权限,而不必检查该目录。Daniel对dirname也是这么说的,永远不要在默默无闻的情况下尝试安全。这是一个几乎不起作用的坏主意。相反,做一些经过验证的事情,比如沙箱、加密等。假设“填充”中包含由同一用户创建的文件,则允许此程序仅删除用户拥有的文件。我需要检查的是正斜杠吗?不知怎的,它不能逃脱吗?我想到的web服务有很多方法可以绕过这些简单的测试,使用各种方式对字符进行编码/转义。不,它不能逃脱。路径名的规则比URL的规则简单得多。我只需要检查正斜杠吗?不知怎的,它不能逃脱吗?我正在考虑web服务w