我正在用bash
编写一个实用程序集合,其中包含一个公用库。我编写的每个脚本都必须有一个代码块,用于确定库相对于可执行文件的路径。不是实际的代码,而是一个示例:
#!/bin/bash
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. $DIR/../lib/utilities/functions
我没有使用前言来搜索库,而是有了一个聪明的想法,使用环境变量来指示库的位置。
#!/bin/bash
. $TOOLS_LIBRARY_PATH
我可以使用包装程序来设置该环境变量,也可以在我自己的路径中设置它。可能有更好的方法来组织bash
工具集,但问题是:
我可以信任我的环境变量吗?
这是我从来没有真正想过的问题之一。当用其他语言编程时,路径被用来查找库(例如LD_LIBRARY_PATH
、PYTHONPATH
、PERLLIB
、RUBYLIB
、CLASSPATH
、NODE_PATH
),但我从未停下来思考这怎么可能是不安全的。
事实上,LD_LIBRARY_PATH
有Why LD_LIBRARY_PATH
is bad来阻止它的使用。如果分别调用了Ruby和Perl库路径环境变量的安全机制,则它们将被忽略,分别为$SAFE
和-T
(taint mode)。
到目前为止我的想法..。
TOOLS_PATH_LIBRARY
设置为他们选择的库,但实用程序将在他们的uid下运行。他们可以简单地使用bash
.sudo
某些东西直接运行他们的恶意库。有人可以将他们的TOOLS_PATH_LIBRARY
设置为利用这一点的东西。但是,这些工具并不是通过sudo
运行的,它们只是在各处调用sudo
。用户在任何情况下都必须是sudoer
,他们可以直接调用sudo
。TOOLS_PATH_LIBRARY
,那么我就不能信任PATH
。所有的程序调用都必须使用绝对路径。ls
,而是使用一个变量,比如LS=/bin/ls
。据我所知,这是为了防止用户将程序默认设置重新定义为别名。请看:PATH, functions and security. Bash scripting best practices. .我已经把这个rubber ducked成了一种答案,但我还是要把它贴出来,因为它不是一个很好的答案。
更新:使用环境变量指定库和可执行文件的路径有哪些安全问题?
发布于 2012-04-11 01:12:04
简短的回答:
假设用户能够运行自己选择的程序和代码,那么您不必信任他们提供给您的任何东西,包括环境。如果帐户在某些方面受到限制(没有shell访问权限,没有对允许执行的文件系统的写访问权限),这可能会改变情况,但只要您的脚本只做用户自己可以做的事情,为什么要防止恶意干扰呢?
更长的答案:
在安全问题方面,至少有两个单独的问题需要考虑:
如果且只要您的程序是在启动程序并提供所有输入的用户ID下运行的(即,唯一可以发起任何攻击的用户),那么只有在极少数情况下才有必要强化程序以抵御攻击。防拷贝保护和共享高分在脑海中浮现,但这一组事情不仅与输入有关,而且可能更重要的是阻止用户读取代码和内存。在不使用suid/sgid技巧的情况下隐藏shell脚本的代码是我不知道该怎么做的;我能想到的最好的方法就是隐藏代码。
在这种情况下,用户可以欺骗程序做的任何事情,他们也可以在没有工具的帮助下做,所以试图“保护”免受该用户的攻击是没有意义的。你的描述读起来并不像你真的需要任何针对攻击的保护。
假设您确实需要保护,那么您就不能依赖环境变量-如果您不能重置LD_LIBRARY_PATH
和LD_PRELOAD
之类的东西,那么即使调用具有绝对路径的工具(如/bin/id
或/bin/ls
)也不会给出可靠的答案,除非该工具恰好是静态编译的。这就是为什么sudo
在默认情况下启用了env_reset
,以及为什么运行suid程序必须忽略某些环境变量。请注意,这意味着您认为TOOLS_PATH_LIBRARY
和PATH
同样值得信任的观点在您的情况下可能是正确的,但在其他情况的边界情况下不一定是正确的:系统管理员可能会针对sudo
的使用重置PATH
,但允许非标准环境变量通过。
如上所述,argv[0]
(或其bash等效项${BASH_SOURCE[0]}
)并不比环境变量更可靠。用户不仅可以简单地制作原始文件的副本或符号链接,而且execve
或bash的exec -a foo bar
允许将任何内容放入argv[0]
。
发布于 2012-04-11 02:55:34
你永远不能相信别人的环境。
为什么不简单地创建一个包含所有这些重要代码的新用户。然后,您可以直接从/etc/passwd
获取信息,也可以使用~foo
语法查找用户的主目录。
# One way to get home directory of util_user
DIR=$(/usr/bin/awk -F: '$1 == "util_user" {print $6}' /etc/passwd)
# Another way which works in BASH and Kornshell
[ -d ~util_dir ] && DIR=~util_dir
# Make sure DIR is set!
if [ -z "$DIR" ]
then
echo "Something's wrong!"
exit
fi
https://stackoverflow.com/questions/10090014
复制相似问题