9

为了保护应用程序不被错误地使用,我正在尝试检查其配置文件是否具有正确的权限,以便应用程序可以信任文件的内容不会被其他人修改。

我相信以下规则是正确的:

  • 该文件不能被其他人写入
  • 该文件必须由受信任的用户/组拥有: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,但它负责检查组写入位。

问候。

4

2 回答 2

8

您的规则和代码在我看来是正确的,但您应该注意以下可能仍会影响您的实施的安全风险。

  1. 对机器具有物理访问权限或 NFS/SMB 访问权限的攻击者可以使用具有 root 权限的机器安装文件系统,然后修改您的文件。
  2. 作为受信任用户或 root 运行的另一个程序中的漏洞可能允许该程序被利用来修改您的文件。
  3. 破坏您的安全检查所需要的只是粗心的用户或系统管理员弄乱了文件的权限设置。我已经看到在备份和复制到拇指驱动器等过程中发生这种情况。
  4. 还要确保该文件不可执行。我想不出一个可以在配置文件上利用它的实例,但是安全的一般规则是不提供工作不需要的任何特权。

如您所见,这些问题不在您的代码控制之下。因此,在向他们保证配置文件的不可篡改之前,您应该确保您的客户了解这些风险。

于 2013-05-23T20:31:56.287 回答
7

我相信您还想检查目录的权限。

如果允许用户写入目录,则用户将能够使用mv属于正确用户的另一个文件来替换该文件。

就像是:

sudo touch foo.conf
sudo touch foo.conf-insecure-sample
mv -f foo.conf-insecure-sample foo.conf
于 2013-05-24T09:39:03.187 回答