在编写的 Web 应用程序中,以下八进制格式的完美最小权限是什么?
- 用户上传静态文件(images/swf/js 文件)的目录
- 管理员上传静态文件(images/swf/js 文件)的目录
- 应用程序中使用的库所在的目录
- 可执行/可浏览的服务器端脚本所在的目录
- 服务器端代码将编辑已存在文件(txt 或 xml)的目录
以下是我的建议和理由
- 555,每个人都可以读写,但没有人可以执行
- 544,只有所有者可以写入,其他人只能读取,没有人可以执行
- 000,没有人需要读取、写入或执行,只会被网络服务器使用?
- 661,所有者可以读取、写入,其他人只能执行
- 600,所有者可以读取、写入(可能不需要),其他人都无法执行任何操作
现在我对两件事感兴趣:
- 我在第一个列表中遗漏了基于 Web 的应用程序中常用的一些内容吗?
- 第二个列表中是否存在您不同意的内容,您的替代方案是什么,以及为什么它更好?
答案1
假设“Web 应用程序”在服务器上运行(如 apache、nginx 等)并以某种动态脚本语言(如 PHP、Ruby 等)编写,那么您对“用户”是谁存在误解。
用户不是登录到您的应用程序的人 - 他们在应用程序中的角色(管理员等)与场景完全无关。用户是进程在其下运行的 Linux 系统用户。您的网站的代码仅以一个用户的身份运行 - 它可能是您的网络服务器的用户(这不是一件好事),也可能是特定于您网站的用户(这要好得多)。
在 Linux 上,用户属于组 - 我们可以将用户添加到另一个组并为该组分配权限。
一个好的设置将使您的服务器作为一个用户运行(我们称该用户为“webserver”)并且您的动态脚本语言以其自己的用户运行(例如通过 FastCGI)(每个站点一个用户 - 我们称我们的第一个用户为“site1”)。
为了提供您的文件,Web 服务器需要访问它们,脚本语言也需要访问它们。这意味着:“site1”和“webserver”需要能够读取您的文件。但是,只有其中一个可以“拥有”这些文件。所有者是“用户”(用户、组、其他)。我们还需要我们的脚本语言能够写入目录(并读取它写入的文件)。因此,用户“site1”需要读写权限。由于我们希望组和其他权限尽可能严格,我们的“所有者”将是“site1”,相应的用户权限将是读写。
由于我们无法将我们的网络服务器的权限指定为另一个“用户”,我们将把“网络服务器”添加到“site1”组(当然,您可以创建一个包含“site1”和“网络服务器”的不同组)。该组的所有成员都将被赋予相同的权限。最宽松的权限(用户、组、其他集合)将应用于任何给定用户以确定他们的权限。
值得注意的是,良好的设置不应要求文件具有动态语言的执行权限。这些文件不会直接运行,而是被读入解释器 - 运行典型脚本(不写入任何内容的脚本)只需要读取权限。
目录的“执行”权限具有不同的含义 - 它允许遍历但不能读取内容。为了能够读取目录中的文件,用户必须对其上级的每个目录都具有“执行”权限。
对于 Web 应用程序,每个文件都必须具有其所有者的读取权限 - 否则,它就是一个毫无意义的文件。无论是用户还是管理员上传文件(通过您的 Web 应用程序),“所有者”(即动态语言)都需要写入权限。有效的设置将尝试直接通过 Web 服务器提供静态文件,因为动态语言在读取大型文件和回显内容时往往很慢。因此,Web 服务器需要对您的静态文件具有读取权限。
因此,最小文件权限可能是:
- 用户上传静态文件(images/swf/js 文件)的目录中的文件将驻留:640
- 管理员上传静态文件(images/swf/js 文件)的目录中的文件将驻留:640
- 应用程序中使用的库所在目录中的文件:400(或 440)
- 可执行/可浏览的服务器端脚本所在目录中的文件:400(或 440)
- 目录中已存在的文件(txt 或 xml)将由服务器端的代码编辑:640 或 600
- (取决于网络服务器是否显示这些内容,有时不作修改)
而最小目录权限可能是:
- 用户上传静态文件(images/swf/js 文件)的目录将驻留:750
- 管理员上传静态文件(images/swf/js 文件)的目录将驻留:750
- 应用程序中使用的库所在的目录:500(或 550)[至少应为 510]
- 可执行/可浏览的服务器端脚本所在的目录:500(或 550)[至少应为 510]
- 服务器端代码将编辑已存在文件(txt 或 xml)的目录:750 或 700
- (取决于网络服务器是否从这里提供文件,有时不作修改)
再一次 - 您的 Web 服务器必须对其需要访问的目录之上的每个目录都具有“执行”权限 - 因此即使 Web 服务器不会提供给定目录中的文件,我们也应该授予它执行权限。
授予 Web 服务器对大多数文件的读取权限是相当常见的(因此将 500 改为 550)。默认的“相对安全”权限通常为目录 755 和文件 644 - 无执行权限,每个人都可以读取,只有用户可以写入 - 您会注意到 Linux 系统上的绝大多数文件都具有这些权限。
请记住,“其他”权限指的是任何非所有者或非组内的系统用户(即所有剩余的系统用户)。限制“其他”权限是明智之举,因为这些用户是未知的 - 您没有明确授予他们权限。其他权限通常是受感染系统上最容易被利用的权限(例如,这也是 /tmp 成为常见目标的原因之一)。
在上述情况下,我认为您的最后两个问题不太相关。将目录权限设置为 550(将文件权限设置为 440),然后授予用户对您的应用程序将写入的任何目录的写入权限(即目录:750;文件:640)。
(您显然需要写权限才能上传文件 - 但如果您愿意,您可以在之后删除这些权限 - 但可以说,如果有人正在写入只有所有者可以写入的目录 - 您的帐户已被泄露 - 这是保留限制权限的原因之一)。
答案2
拥有完成工作的最低权限集是正常的。如果您的 Web 服务器和用户共享一个共同的组,那么您可以消除授予任何访问权限的需要o
。权限也与用户有关。您似乎误解了八进制权限。
- 555 不是
r-xr-xr-x
。rw-rw-rw
因为它是一个目录,所以要创建/删除文件,您需要设置x
750,所以 750rwxr-x---
是一个不错的起点。这允许拥有该目录的用户添加/删除文件,并允许公共组中的所有人访问它们。 - 同上1.。
- 如果它们确实是静态文件,那么 050 将授予 Web 服务器访问权限,然而,首先创建文件时 750 是最低限度。
- 同上3。
- 070 是允许网络服务器读取和更改文件的最低限度,但需要创建文件,因此 770 可能更为现实。
答案3
通常,人们会在目录上使用模式 0755、0775 或 2775(对于 BSD 和 Linux,如果文件系统使用 BSD 语义挂载,目录上的 SGID 位将使新文件的组关联与父目录设置相匹配,而不是与文件创建者的默认 GID 相匹配)。这允许所有用户遍历(进入和遍历 chdir)和读取(运行 ls 命令或执行 readdir/read 系统调用)相关目录。替代方案添加了组/写入选项,并且如上所述,目录上的 SGID 位可以帮助将所有文件和子目录与合适的组相关联。
对于文件,通常使用 0644 或可能 0664(世界可读,组可写或不可写)。显然,对于 CGI 脚本和二进制文件,必须添加 x 位;对于某些特殊情况,对于经过极好测试的二进制文件,可以添加 SUID 或 SGID 位。通常,UNIX 和 Linux 会忽略脚本上的 SUID/SGID 位,并且只遵守其对本机编译的可执行二进制文件的语义。但是,您可能在 Apache 之类的系统下运行您的站点,并使用“setuidhack”之类的模块,该模块可用于使 Web 服务器即使在解释脚本上也遵守 SUID/SGID 位。(这是通过 HTTP 守护进程 stat()ing 每个文件并使用其自己的自定义 fork()/execve() 代码,将正确的解释器字符串插入 execve() 向量来完成的,而不是简单地将可执行文件的名称直接传递给 execve() 系统调用)。
这些只是最通用的指导原则。它们并非适用于所有情况,您一定要查阅 Web 服务器以及您正在安装和配置的任何 Web 应用程序或框架的文档……在将任何文件、代码或服务器暴露给公共互联网之前,您可能希望咨询 UNIX 安全专家。