这是一个我似乎找不到的问题好的回答。
在 Windows/DOS 下,我们已经被“教导”可以从当前目录启动程序而无需在路径前添加前缀。
但是,Linux 的默认行为是必须在当前目录中的应用程序/脚本前面加上 ./。
人们说,允许程序/脚本在不添加目录前缀的情况下执行是一种不好的安全做法。有很多“不好的安全做法”,但这个对我来说毫无意义。例如,我不会进入 /some/unfamiliar/directory 并开始执行像 ls 这样的程序。我会 cd(转到我的主目录),然后输入 ls -la /some/unfamiliar/directory。当然,在糟糕的日子里我会这么做。
如果有人将名为 ls 的程序放在目录中,而一个坏的系统管理员 cds 到该目录并以 root 身份运行 ls,那么 ls 会添加后门用户和其他邪恶的东西,我可以看到这种“威胁”。很好。但是,通常在这种情况下,用户会抱怨“哦,ls 不起作用,你能检查一下吗?”。我会 sudo su“用户”,然后以他的身份尝试 ls。
除非我完全忽略了一些东西,否则在 PATH 中添加“。”真的有那么糟糕吗?
编辑:
到目前为止,所有答案都很好地指出了安全风险 - 但是 - 每个人都忽略了 Windows 的参数。在 Windows 下,当前目录不在您的路径中,因此据我所知,没有办法禁用仅运行 program.exe 的功能。但是,命令提示符确实接受在命令前加上 .\ 的功能(.\ 似乎有效,但是,您应该使用 \,否则您可能会得到某种转义序列)。在 Windows 下,我们应该始终在命令前加上前缀吗?此外,我们是否应该联系 Microsoft 并告诉他们植入这种预期行为是错误的?
我的背景是 Windows,所以我总是期望当前目录中的程序能够运行,尽管我知道在 Unix 世界中它不是这样运行的。这就是我提出这个问题的原因。
扩展我对“不良安全实践”的含义(以及为什么将它们放在引号中)是因为我们可以列举数百万甚至数十亿种人们应该遵循的安全实践……但我们没有这样做,如果我们这样做,一个人肯定会发疯。我们是否应该减轻可能干扰用户体验的每一个安全风险?我说不,但那是因为我相信安全性应该对用户透明,但我喜欢 haus 在他的回复中的第一句话“与其他任何事情一样,这是一种心态。”。我认为我们应该就此打住。
答案1
和其他任何事物一样,这是一种心态。
通过将当前目录作为路径的一部分,您确实会增加风险。仅仅因为木马程序已经执行,并不意味着它不会做人们期望它做的事情。换句话说,使用您的 ls 示例,除非木马程序是由傻瓜设计的,否则它确实会为您提供您请求的目录列表,因此除非您说出文件位于那里,否则您没有理由认为出了问题(也许它会很聪明,决定将自己从提供的目录列表中删除,以进一步降低检测到的机会)。
如果发生这种情况,则意味着有人已经渗透到某个系统,可以将文件放入您的文件系统中。因此,您已经处于困境之中,但情况仍有可能变得更糟。
作为一般做法,我不会将当前目录放在 Linux/Unix 系统上的路径中,这不会带来太大的麻烦。当我编写一个希望经常使用的程序或脚本时,我会将其放在路径中的文件夹中,并限制对该文件的写入权限。
简短的回答,将当前目录添加到路径中是否会给非特权用户带来一定损失,可能不会,但为什么要冒这个险呢?
对于 root,不要这样做。
答案2
对于 root 用户来说,这是致命的。对于其他用户,我建议不要在路径中添加“。”(以及出于安全考虑)的原因是,它会导致您遇到奇怪且令人困惑的问题,例如,搜索路径的进程可能会开始花费非常不同的时间,或者找到同名的不同程序。例如,solaris 上的 /usr/ucb 包含 BSD 版本的 ps 命令。创建一个新的文件系统,并用大量文件填充它,然后在路径中使用“。”尝试对“grep”执行 bash 补全。这将花费更长的时间,因为必须搜索 .,并且其中有一百万个文件。“。”也可能位于一些非常慢的媒体上,例如非常远的 NFS 安装或类似的东西。您可能会侥幸逃脱,并且永远不会看到它导致问题,但是当它确实导致问题时,可能不会立即发现根本原因是什么。我见过很久以前许多性能问题都是由非常长的 PATH 引起的,PATH 在不同环境中不一样等等。我的 2D:在您自己的盒子上,在您自己的用户上,如果这能让生活更轻松,那就去做吧。在生产中,不要让点出现在路径上。
答案3
如上所述,最明显的安全风险就是当前目录中存在一些恶意代码,这些代码会取代现有的可执行文件。这是否可被利用实际上取决于您对“不要从未经审查的目录运行命令”策略的严格程度。
然而,可能出现的一个更微妙、更严重的问题是,命令的解析是不再可预测。例如,如果您习惯于在 BASH 中runcommand
键入runc<tab>
,这将在大多数目录中工作,但如果您恰好在具有可执行文件的目录中,则会失败runcom
。同样,只要清楚自己在做什么,就可以避免这种情况,但根据我的经验,在输入runc<tab>
五十次而没有问题之后,第五十一次很容易被忽视。
令人讨厌的是,它不涉及任何恶意意图。没有病毒感染您的系统,也没有特洛伊木马偷偷植入您的主目录。这只是两个不同的命令,在两个不同的目录中,执行两件不同的事情。 runcom
可能非常合法地只需要从您的主目录中删除一半的文件,但这并不意味着您想意外运行它。
如果您正在处理脚本,这可能会更加危险。如果您从命令行运行典型的 shell 脚本,它将采用您的 $PATH 变量。与上述示例类似,这意味着如果您从不同的目录运行脚本,脚本行为可能会有所不同。如果您不是使用/usr/bin
该/usr/local/bin
版本,则最终可能会运行任何给定命令的不同版本。或者,您最终可能会得到可用的命令,这些命令通常会在丢失时标记合法错误——比重要脚本意外失败更糟糕的少数事情之一是所述脚本意外失败和思维成功了。编写良好的脚本可以通过设置自己的 $PATH 或通过明确调用以完整路径名开头的命令来解决这个问题。
并非所有脚本都写得很好。
只需将当前目录设置为路径中的最后一个解析点而不是第一个解析点(PATH=$PATH:.
而不是PATH=.:$PATH
),即可解决许多此类问题,但这仍然不是一个完美的解决方案。鉴于明确在命令前加上前缀以./
运行本地目录版本只需额外按两次键,我会坚持这样做。
答案4
由于 pwd 位于速度较慢的远程文件系统上,因此会出现以下问题:如果 . 由于某种原因不再存在,您将无法再运行除 shell 内置命令之外的命令,这非常令人困惑。pwd 可能已被删除,包含它的文件系统可能已被强制卸载,或者位于已关闭的服务器上。