Debian 升级到 exim4 4.94 带来了新的麻烦:受污染的变量。
我有几个由我的 exim 处理的虚拟域,因此我使用变量扩展来获取 DKIM 域、选择器和密钥。在我的000_localmacros
是:
DKIM_CANON = relaxed
# Get the domain from the outgoing mail.
DKIM_DOMAIN = ${sg{${lc:${domain_data:$h_from:}}}{^www\.}{}}
DKIM_SELECTOR = ${lookup{DKIM_DOMAIN}lsearch{/etc/exim4/dkim/selector.map}}
# The file is based on the outgoing domain-name in the from-header.
DKIM_FILE = /etc/exim4/dkim/DKIM_DOMAIN/DKIM_SELECTOR/private.key
# If key exists then use it, if not don't.
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
(这些变量随后将在 Debian 的默认文件中使用transport/30_exim4-config_remote_smtp
)。
不幸的是这会产生:
2021-09-10 07:13:27.625 [28932] 1mOYqk-0007WN-8p Warning: Tainted filename '/etc/exim4/dkim/example.com/n201711/private.key'
请注意,我确实按照文档的建议替换了$domain
已经$domain_data
,但它没有帮助。
我该如何解决这个问题以便删除我的allow_insecure_tainted_data = yes
声明?
答案1
喜欢你的开场白。
我遇到了类似的问题,我在主配置部分使用以下宏:
DKIM_DOMAIN = ${lc:${domain_data:$h_from:}}
DKIM_SELECTOR = ${lookup{$dkim_domain} lsearch {/etc/exim4/dkim/tags} {$value} {defaultdkimtag}}
附有/etc/exim4/dkim/tags
如下文件:
mydomain.org: sometag
myotherdomain.org: 12345
但DKIM_DOMAIN
结果是“受污染的”,因为$h_from
它是由(潜在的)攻击者设置的。要清除它,您必须将其替换为已知安全的查找。
我这样做的方法是:
DKIM_DOMAIN = ${lookup{${lc:${domain:$h_from:}}} lsearch,ret=key {/etc/exim4/dkim/tags}}
- 从(被污染的)
$h_from
... - 使用 提取域
${domain:...}
。这仍然会被玷污。 - 强制将其转为小写
${lc:...}
。只是因为。仍然被污染 - 在标签文件中使用 lsearch 查找小写的受污染域。这里我使用了该
ret=key
选项,这意味着雷特查找得到的值将是“替换为未受污染版本的查找密钥” - 所以它现在未被污染,因此不会污染其他宏等中的后续使用。
你的配置是
DKIM_DOMAIN = ${sg{${lc:${domain_data:$h_from:}}}{^www\.}{}}
看起来是${domain_data:$h_from:}
错误的 -${domain_data:...}
未列为字符串扩展。$domain_data
是一个有效的变量,但这不是您想要在那里做的事情 - 我认为,像我一样,您正在尝试从 中提取域$h_from
。所以在这里我认为你应该使用${domain:$h_from:}
(我也不确定末尾的冒号是什么,但我将其留给你)
那么你就会:
DKIM_DOMAIN = ${sg{${lc:${domain:$h_from:}}}{^www\.}{}}
但这仍然会受到污染,因为您允许在文件路径中使用任何外部提供的值。
所以我建议采用以下解决方案:
FROM_DOMAIN_WITHOUT_WWW = ${sg{${lc:${domain:$h_from:}}}{^www\.}{}}
DKIM_DOMAIN = ${lookup{FROM_DOMAIN_WITHOUT_WWW} lsearch,ret=key {/etc/exim4/dkim/selector.map}}
或者,如果您不喜欢额外的宏:
DKIM_DOMAIN = ${lookup{${sg{${lc:${domain:$h_from:}}}{^www\.}{}}} lsearch,ret=key {/etc/exim4/dkim/selector.map}}
答案2
我找到了一个解决方案,但我不确定它是否适用于嵌套目录。
我刚刚将其更改DKIM_PRIVATE_KEY
为:
DKIM_PRIVATE_KEY = ${lookup {DKIM_SELECTOR.DKIM_DOMAIN.key} dsearch,ret=full {/etc/exim4/dkim}}
而是将密钥存储在平面目录中作为selector.domainname.key
.