![如何避免在 Exim 的 ${run{...}} 扩展中用空格破坏参数?](https://linux22.com/image/4355/%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%9C%A8%20Exim%20%E7%9A%84%20%24%7Brun%7B...%7D%7D%20%E6%89%A9%E5%B1%95%E4%B8%AD%E7%94%A8%E7%A9%BA%E6%A0%BC%E7%A0%B4%E5%9D%8F%E5%8F%82%E6%95%B0%EF%BC%9F.png)
我有一个程序,/usr/local/bin/rt_queue_exists
它需要一个参数。如果参数听起来不错,则程序以状态 0 退出;否则非零。根据该程序,我想要一个仅在本地部分气味良好时才接受消息的路由器。
此外,该程序依赖于一个只能由 root 和 www-data 读取的配置文件,因此我认为我应该配置 sudo 以允许rt_queue_exists
Exim 作为 www-data 调用。
因此,我在路由器选项中提出了这个:
condition = ${run{/usr/bin/sudo -u www-data /usr/local/bin/rt_queue_exists $local_part}{yes}{no}}
通常,它可以工作,除非本地部分有空格(是的,这是允许的)。当本地部分有空格时,rt_queue_exists
调用二论据。
这很糟糕,因为:
- 我的一些队列名称中有空格
- 如果我可以用空格更改命令,我可以执行更严重的注入攻击吗?
bash 中也存在类似的问题:
cat $file # BAD! NO!
cat "$file" # good!
exim 中的类似解决方案是什么?
答案1
虽然这不是直接解决您的问题,但我避免使用 exim,它是发送字符类问题的通用解决方案,这些字符是通过非八位干净的数据通道专门处理的,不会触发中的特殊含义数据通道。
对所有特殊字符进行编码。在这种情况下,给您带来麻烦的字符是值为 0x20 的空格,因此您可以创建特殊用途的编码,或者找到可以正常工作的库存编码。我会推荐 url 编码,因为它很简单,有据可查,设计用于处理类似的问题(CGI),有多个现成的实现,并且可以使用正则表达式来实现捕获观察到的问题的简单子集与bash一起来吧。为了快速总结 url 编码,所有出现问题的字符都被替换为由%
(0x25) 组成的三个字符串,后跟两个十六进制字符的值,否则会出现问题。例如,如果我们有字符串“eat $%!&”,则会带来麻烦的两个字符是空格和百分比,因此编码后我们将得到“eat%20$%35!&”,其中没有 exim 的空格窒息。我们在另一侧反转该过程,以取回原始字符串。我包含了以下两个 sed 脚本来编码和解码仅处理提到的两个特殊字符的字符串。
s/%/%35/g
s/ /%20/g
s/%20/ /g
s/%35/%/g
请注意,在编码期间,首先对百分比进行编码,在解码期间,最后对百分比进行解码。