Rus*_*uss 13 security bash sudo parameter shell-script
这个问题是完全通用的,不仅适用于我的情况,而且......我有一个小的 busybox 设备,我希望非 root 用户能够以 root 权限执行特定的脚本。例如,类似于这个启用 DHCP 的小脚本,其中$1
在 cmdline (!!) 上发送的唯一变量 ( ) 是要发送的主机名:
#!/bin/bash
udhcpc -b -i eth0 -h $1
Run Code Online (Sandbox Code Playgroud)
像这样运行 udhcpc 需要 root 访问权限,因此为此我计划修改/etc/sudoers
以包含以下行:
joe ALL = NOPASSWD: /path/to/enable_dhcp.sh
Run Code Online (Sandbox Code Playgroud)
这应该使“joe”能够通过简单地运行以root权限轻松运行该脚本:
sudo /path/to/enable_dhcp.sh
Run Code Online (Sandbox Code Playgroud)
并且没有被要求输入密码(这是我想要的,因为我希望 joe 能够编写此脚本)。
现在..我知道(或者至少我认为我知道)$1
在一个可以很容易地以 root 权限运行的脚本中使用是一个可怕的想法,因为你可以注入任何你想要的东西。
那么......处理这个问题的最佳方法是什么?我如何让 joe 以 root 权限做我想做的事,允许他传入一个变量(或者像使用环境变量那样有效地这样做),同时又不会对注入攻击敞开大门?
Gil*_*il' 14
如果配置为重置环境,则在下面运行 shell 脚本sudo
是安全的。相反,如果不重置环境,则运行 shell 脚本是不安全的,即使您的脚本不使用其参数(请参阅在 shell 脚本上允许 setuid)。确保您有in或此选项是编译时默认值(应包含)。sudo
sudo
Defaults env_reset
/etc/sudoers
sudo sudo -V | grep env
Reset the environment to a default set of variables
使用脚本参数没有特别危险。$1
是一个字符串,您只需要确保将它用作字符串。(例如,不要这样做eval "$1"
。)显然,这里特别重要的是不要对变量的内容进行假设,并在所有变量替换(即 write "$1"
, not $1
)周围加上双引号。请注意,将双引号放在变量替换周围并不是特定于以特权运行的脚本,这是您必须始终执行的操作。
您可能希望进一步验证参数,具体取决于对udhcpc
看起来不像主机名的内容的作用。例如,这将执行第一次语法检查:
#!/bin/sh
case "$1" in
*[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;;
esac
udhcpc -b -i eth0 -h "$1"
Run Code Online (Sandbox Code Playgroud)
您应该将传递的输入与已知的良好模式进行匹配。
例如,看起来 IP 地址可能是您的有效输入。所以你可以使用这样的东西:
if [[ "$1" =~ ^[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9]$ ]]
then
udhcpc -b -i eth0 -h "$1"
else
echo "Don't mess with me pork chop."
fi
Run Code Online (Sandbox Code Playgroud)
请注意,regexp 尚未经过测试,您有责任确保您的 regexp 不允许任何危险。
归档时间: |
|
查看次数: |
3236 次 |
最近记录: |