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