如何从 #!/bin/sh 脚本中的参数中获取有效路径?

如何从 #!/bin/sh 脚本中的参数中获取有效路径?

我有一些脚本(副本)并想获取有效路径。

#!/bin/sh
cp -R $1 $2

我尝试使用这样的参数

./copy.sh /home/apple /home/pie;reboot

然后服务器重新启动,这在生产服务器中是不可接受的。

我知道 linux 路径仅由 [a-zA-Z0-9_-/. ] 组成。

我怎样才能过滤掉 1 美元和 2 美元,这样我就可以放心打电话了。

#!/bin/sh
$filtered_path_1=some_filter_funtion($1)
$filtered_path_2=some_filter_function($2)
cp -R $filtered_path_1 $filtered_path_2

背景

我有 jenkinsfile,并在此 jenkinsfile 中调用 sh 'sudo /home/copy.sh ${Workspace} ${targetdir}'。由于 jenkins 用户对 ${targetdir} 没有写权限,因此我通过以下方式仅授予 jenkins 用户此 copy.sh 脚本的 root 权限

sudo visudo jenkins    
ALL = NOPASSWD: /home/copy.sh, 

这个 jenkinsfile 位于 git 存储库中。如果坏人使用诸如 reboot 之类的恶意代码修改此 jenkinsfile 并提交,则会自动调用复制脚本。由于此脚本是在 root 权限下调用的,因此他可以利用此弱点做坏事。他将删除 sh 'sudo /home/copy.sh ${Workspace} ${targetdir}',并添加 sh 'sudo /home/copy.sh /tmp /var;reboot'。

我该如何保护他?

答案1

这与您的脚本无关。在 Bash shell 中,;被视为命令字符串的终止命令,紧接着是次要命令。因此,实际上您的内容的处理方式如下。

  1. 在之前执行命令;

    ./copycron.sh /home/apple /home/pie
    
  2. 执行之后的第二条命令;

     reboot
    

因为您正在以root超级用户身份执行,所以它已成功重新启动。

但是,如果您执行更具体的操作并在之后执行另一个任意命令;,您会注意到该命令会运行。您脚本的两个参数将分别保留/home/apple/home/pie。脚本永远不会看到该;reboot部分,因为它不会被解析为参数。这是 Bash 的限制,而不是脚本中的某些内容。


您可以使用以下脚本进行测试,然后执行命令调用:

文件:argecho.sh

#!/bin/bash

echo "Space delimited arguments: $*"
echo ""
echo "------"
echo ""

执行命令: ./argecho.sh foo bar baz /tmp/something.txt;echo I Did Something Else

输出:

$ ./argecho.sh foo bar baz /tmp/something.txt;echo I Did Something Else Outside The Script, see?
Space delimited arguments: foo bar baz /tmp/something.txt

------

I Did Something Else Outside The Script, see?

您会注意到,'echo' 及其中的其他参数未包含在脚本中的参数中。这是标准 Bash 行为。



根据您的编辑,您担心有人会劫持您的 Jenkins 存储库命令并发出恶意命令,方法是将脚本从 更改sh 'copycron "${Workspace}" "${targetdir}"'sh copycron /home /boot;shutdown

不幸的是,这绝对没有办法解决,这将导致您无法正确控制谁有权访问命令存储库。此类威胁行为者将拥有更多访问权限来破坏您的系统,而不仅仅是运行上述更改之类的简单命令。他们更有可能在您的系统上安装恶意软件,而不是任何东西,除非您妥善保护命令存储库,以便没有人可以“随意编辑它们”,否则您对存储库缺乏控制将使您陷入困境。

如果 jenkins 用户拥有无限的 sudo 权限,我们在这里也无法进行真正的强化。根本就不行,因为这将依赖于您正确地保护您的系统或构建一种更安全且不需要完全处理sudo所有事情的替代部署机制。

相关内容