PHP 和文件系统+setUID/权限...我只是不明白!
我不得不承认,我从未真正完全获得 *nix 文件系统权限模型。哦,rwxrwxrwx 的东西并不太复杂,但是当程序创建新文件以及如何处理它们时,我很容易感到困惑。
我当前的问题是(闭源)java小程序的混合,它通过ftp和php上传文件(它位于专用服务器上,数据并不真正重要,所以我不太关心世界可写性)。
所以,我有两个用户:ftp(1000)和apache/php(81)。团体不匹配,所以他们基本上是“其他”,如果我是正确的。
一个“导入”目录,设置为 ftp 拥有的 0777。
如果访问者访问上传页面,我的脚本将创建一个以他的用户名命名的子目录。假设访问者的用户名是“foo”,所以它是“import/foo”,设置为0777,用户81/php。
接下来,访问者使用java小程序将文件上传到该目录(test.jpg)。文件的权限现在为 rw-r--r--,用户为 ftp。
第一个问题
我不明白的第一件事是:我能够通过 php 取消链接该文件。
为什么?用户不匹配,并且该文件不是全局可写的。
这是因为父目录的世界写入权限吗?可以理解的是,我无法通过 php 进行 chown 或 chmod 操作。
到目前为止没有问题,因为只要我可以读取并取消链接,一切就可以了。
第二个问题,
java小程序能够上传整个目录,这很好。如果我这样做,新的子目录 import/foo/test 具有 rwxr-xr-x/ftp 权限。该目录中的文件为rw-r--r--/ftp。
现在我运气不好了。我无法对这些文件做任何事情(除了阅读,我成功地做到了),没有取消链接,没有 chmod/chowning。他们只是坐在那里吞噬磁盘空间。
那么,新文件的默认权限背后的计划是什么?我的猜测是,只要创建脚本不将它们更改为其他内容,他们就有通过 umask 设置的权限。我说得对吗?
第三个问题
我能做什么?我的意思是,一个明智的人会做什么?我可以/应该更改 ftp 用户的 umask 吗? (我昨天刚刚了解了 umask)。我对此不太满意,因为这会影响所有 ftp 流量,不是吗?另外,服务器是专用的,但我不是管理员,所以我的访问受到限制。
我只是有另一个想法。在开始这篇文章之前,我阅读了基本的 Linux 权限知识。首先,粘滞位没有设置在目录链中的任何位置。然后,就是:“设置用户 ID 位”。
因此,我当前的计划是使用所有者 ftp 编写一个简单的 shell 脚本,该脚本可以使用 setuid 进行其他执行。该脚本只是将导入目录中的文件所有权转移给用户 php。
然后,每次导入后,我只需从我的 php 脚本中 exec()
该文件并进一步处理文件。
那行得通吗?更重要的是:这是否干净合法?或者系统管理员会悬赏我的人头吗?
非常感谢!
更新:我只是尝试通过winscp(通过ftp连接)设置uid位(4755),但它不知何故不起作用 - 它似乎只“忘记”了uid位(另一个)位已设置)。这是为什么?为什么车主不能自己设置uid?这是特定于服务器的还是一般情况?
更新2:
维基百科说明了一切
由于安全漏洞的可能性增加,许多操作系统在应用于可执行 shell 脚本时会忽略 setuid 属性。
root 用户还可以设置 uid 位吗?
i have to admit, i never really completely got the *nix filesystem permission model. oh, the rwxrwxrwx stuff isn't too complicated, but i get confused easily when programs create new files and how i can handle them.
my current problem is the mixture of a (closed source) java-applet that does file uploads over ftp and php (it's on a dedicated server and the data isn't really critical, so i'm not all too concerned about world-writeability).
so, i have two users: ftp (1000) and apache/php (81). groups don't match, so they're basically "others", if i'm correct.
an "import" directory, set to 0777 owned by ftp.
if a visitor acesses the upload page, a subdirectory named after his username is created by my script. let's say, the visitors username is "foo", so it's "import/foo", set to 0777, user 81/php.
next, the visitor uses the java applet to upload a file to this directory (test.jpg). the file's permissions are now rw-r--r--, user ftp.
first question
the first thing i don't understand is: i'm able to unlink that file through php.
why? the users don't match, and the file isn't world writeable.
is this because of the parent directories world-write permission? understandably, i can't chown or chmod through php.
so far no problem, because as long as i can read and unlink, everythings ok.
second question
the java applet is able to upload whole directories, which is nice. if i do this, the new subdirectory import/foo/test has permissions rwxr-xr-x/ftp. the files in this directory are rw-r--r--/ftp.
now i'm out of luck. i can't do anything with those files (besides reading, which i do successfully), no unlinking, no chmod/chowning. they just sit around and gobble up diskspace.
so, what's the plan behind the default-permissions new files have? my guess is they have the permission set through umask, as long the creating script doesn't chmod them to something else. am i right?
third question
what can i do about it? i mean, what would a sensible person do? can i/should i change the umask for the ftp user? (i just learned about umask yesterday). i'm not very comfortable with this, as this would affect all ftp traffic, doesn't it? also, the server is dedicated but i'm not an admin, so my access is restricted.
i just had another idea. before starting this post i read up on the basic linux permission stuff. first, the sticky bit isn't set anywhere in the directory chain. and then, there it was: the "set user ID bit".
so, my current plan is to write a simple shell script with owner ftp that is other-executable with setuid. the script just transfers the file in the import directories ownership to user php.
then, after each import i just exec()
that file from my php-script and process files further.
would that work? and more important: is that clean and legal? or would the sysadmin put a bounty on my head?
thx a lot!
update: i just tried to set the uid bit (4755) through winscp (through an ftp connection), but it somehow doesn't work - it seems to "forget" only the uid bit (the other bits get set). why is that? why can't the owner set the uid himself? is that server-specific or generally the case?
update 2:
wikipedia says it all
Due to the increased likelihood of security flaws, many operating systems ignore the setuid attribute when applied to executable shell scripts.
is it still possible for user root to set the uid-bit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个答案
正确,您有权修改目录,以便可以取消链接文件。该文件是否可读或可写与您无关。
第二个答案
是的,您是正确的,将使用用户的默认umask,除非脚本/小程序然后将文件权限更改为其他内容
第三个答案
设置ftp的默认umask是最简单的解决方案,但正如您所说,这会影响 ftp 用户创建的所有文件。如果该用户仅用于通过小程序上传(而且应该是真的),那么我想说这并不是一个真正的问题。
另一种选择是运行一个 cron 作业来执行脚本(就像您建议的那样),chmoding/拥有文件(可能还对文件进行病毒扫描等)从 FTP 上传区域到 webroot 上的某个位置。
您没有说明为什么让这些文件只读到 Apache 是一个问题(或者是 FTP 根目录不在 Web 根目录下?),也许澄清这一点将有助于指出一个明智的解决方案?通常,除非您先对其进行了审查,否则您不想相信用户提供给您的任何内容。
编辑 - 刚刚看到你不是机器的管理员,这让事情变得困难。
First answer
Correct, you have permission to modify the directory so you can unlink the file. Whether that file is readable or writable to you is irrelevant.
Second answer
Yes you are correct that the user's default umask will be used unless the script/applet then chmods the file permissions to something else
Third answer
Setting the default umask for ftp is the simplest solution, but as you say this affects all files then created by the ftp user. If that user is only used for the upload via the applet (and it should be really) then this isn't really an issue I'd say.
The other option is to have a cron job running that executes a script (like you suggest), chmoding/owning the files (and maybe virus scanning them etc) from the FTP upload area to somewhere on the webroot.
You don't state why having these files readonly to Apache is an issue (or is it the fact that the FTP root isn't under the web root?), maybe clarifying that would help point to a sensible solution? Generally you don't want to trust anything the user has given you unless you've vetted it first.
EDIT - just seen you're not an admin of the machine which makes things difficult.
我今天学到的东西:脚本的 setuid 位通常被禁用。
我已经确定的解决方案:apache/php 获得某些脚本(webroot 之外的一个目录中的所有脚本)的 sudoer 权限,这些脚本可以作为 ftp 用户或 apache 用户运行。然后我可以使用 sudo 从 php 中使用 system/exec/etc 调用这些脚本。
我不知道 sudo 可以这样配置。 令人惊叹
what i learned today: the setuid bit is often deactivated for scripts.
the solution i've settled on: apache/php gets sudoer-rights for certain scripts (all scripts in one directory outside the webroot) that may run as either the ftp- or apache-user. i can then call those scripts with sudo out of php with system/exec/etc.
i didn't know sudo could be configured in this way. amazing