【发布时间】:2013-05-19 03:23:12
【问题描述】:
为了保护应用程序不被错误使用,我正在尝试检查其配置文件是否具有正确的权限,以便应用程序可以信任未被其他人修改的文件内容。
我认为以下规则是正确的:
- 文件不得被其他人写入
- 文件必须由受信任的用户/组拥有:root 或
- 文件必须由运行应用程序的有效用户/组拥有(想想 setuid 程序)
这里是一个例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
static
int is_secure(const char *name)
{
struct stat st;
uid_t euid = geteuid();
gid_t egid = getegid();
if (stat(name, &st) != 0) {
int err = errno;
fprintf(stderr, "can't stat() '%s': %d (%s)\n", name, err, strerror(err));
return 0;
}
/* writable by other: unsecure */
if ((st.st_mode & S_IWOTH) != 0) {
return 0;
}
/* not owned by group root and not owned by effective group: unsecure */
if (st.st_gid != 0 && st.st_gid != egid) {
return 0;
}
/* not owned by user root and not owned by effective user: unsecure */
if (st.st_uid != 0 && st.st_uid != euid) {
return 0;
}
return 1;
}
int
main(int argc, char *argv[])
{
int i;
for(i = 1; i < argc; i++) {
printf("'%s' : %s\n", argv[i], is_secure(argv[i]) ? "sure" : "unsure");
}
return 0;
}
由于我不确定我的假设,有人可以检查我是否在文件权限检查中留下了一些漏洞。
更新
sudo 有一个功能:sudo_secure_path,它只检查一个 uid/gid,但它负责检查组写入位。
问候。
【问题讨论】:
-
考虑Secure access to files in a directory identified by an environment variable 中的信息。那里的情况更复杂。但是,一些想法是有效的,特别是指向文件的路径也需要是安全的。
-
乔纳森是对的。通向文件的路径中的每个元素都只能由受信任的用户写入,以确保完全安全。否则,可能会发生奇怪的情况,例如移动路径的组件并将其替换为指向不同但相似的目录结构的指针,完全绕过您的文件,但与重写整个配置文件具有相同的效果。根据配置文件中的内容,它可以帮助攻击者闯入或至少进行更明智的 DOS 攻击,因此最好让文件仅由其所有者/受信任的用户读取。
-
@JosephMyers 谢谢。我应该制作一个更完整的示例:此代码用于检查目录和其中的每个文件。
-
@JonathanLeffler 谢谢。我应该制作一个更完整的示例:此代码用于检查目录和其中的每个文件。
-
假设配置目录的父目录是安全的。此外,为了提高安全性,函数
openat()、fstatat()、fstat()用于确保使用检查目录中的文件,而不是其他目录中的文件,移动到应用程序的后面。在打开文件/目录时使用 O_NOFOLLOW 可以防止一些符号链接攻击。
标签: c file security unix permissions