我正在将具有一些自定义过滤器的 exim4 安装升级到 Debian 11。(具体来说,过滤器是这。
由于使用的是 Exim 4.94,我现在遇到了较新的“污染变量”功能,这破坏了我的过滤器。在调试模式下检查 Exim 时,exim4 -bdf -d+filter
错误是指受污染的文件名(为便于阅读,添加了一些换行符):
102536 LOG: MAIN PANIC
102536 Tainted filename for search '/var/spool/exim4/db/disposable-aliases.db'
102536 Filter error: failed to expand
"${lookup sqlite{/var/spool/exim4/db/disposable-aliases.db \
select default_remaining from stem_configs \
where stem = '${quote_sqlite:$local_part}'} {$value}{0}}"
in add command: NULL
102536 Filter: end of processing
在这种情况下,对文件名的引用似乎是虚假的,因为首先文件名是硬连线的(所以不能被污染?)其次,如果我'${quote_sqlite:$local_part}'
用文字值替换查询的部分,错误就会停止(至少从这个特定的查找开始)。
$local_part
因此,我怀疑问题实际上在于查询中的存在,而不是文件名。
我发现$local_part
在某些情况下有一个未受污染的版本可用,$local_part_data
- 但在我的环境中,它没有被设置,因此没有用。
通过进一步搜索,我在 Exim4 文档中找到了这一断言这里:
如果查询中使用了受污染的数据,则应使用适合查找的 ${quote_:} 扩展运算符对其进行引用。
这似乎意味着${sqlite_quote: .. }
扩张应该去污名化$local_data
。这似乎很合理,但这是否真的正确,因为如果我用文字替换扩展,污染问题就会停止?
如果${sqlite_quote: .. }
确实要消除其结果的污染,那么是什么原因导致这次查找被拒绝?
如果不是,那么我还有别的办法吗?上面的 sqlite 查找实际上是设计根据数据库中存储的有效值列表来验证本地部分,并且应该能够消除该值的污染!
我应该补充一点:我不能使用文件查找,因为这个有效列表需要在 exim4 配置文件之外动态配置。
答案1
${quote_
...不进行去污。
并且 exim 污染是针对整个字符串的,因此
在
/var/spool/exim4/db/disposable-aliases.db \
select default_remaining from stem_configs \
where stem = '${quote_sqlite:$local_part}'
仍然受到污染'${quote_sqlite:$local_part}'
,并且污染蔓延至文件名,从而破坏了查找。
exim 规范说你可以将文件名放在单词“sqlite”之后(包含查询的括号外面)
[...] 允许每个查询使用单独的文件,[...] 使用附加选项,以逗号分隔,到“sqlite”查找类型词。选项是单词“file”,然后是等号,然后是文件名
${lookup sqlite,file=/var/spool/exim4/db/disposable-aliases.db \
{select default_remaining from stem_configs \
where stem = '${quote_sqlite:$local_part}'}
exim spec 9.26 - 有关 sqlite 的更多信息
您当前使用的方法已被弃用,因此不再有文档记录。
答案2
只需添加到@Jasen 的答案(使用新的 sqlite 查找语法,问题就会消失),根据所使用的 Exim 版本的不同,会出现一些问题:
- Exim 的错误在这里似乎具有误导性——问题在于数据被污染,但来源不是文件路径,正如它所暗示的那样。
- 我相信污点检查最早是在 Exim 4.93 中添加的(来自 src/README.UPDATING,同时检查源代码历史中的“污点”一词)
- Exim 4.94 已
sqlite_dbfile
实现全局设置,但不支持file=
查找选项。因此无法使用较新的语法并拥有多个 sqlite 数据库。(这是我在 Debian 11 中使用 4.94.2 的经验,并特别提到这里,检查源历史) - 支持
file=
(同上;提交内容为这里)。 - 如果您尝试使用该
file=
选项,Exim 4.94 的错误也会产生误导:它会显示“‘sqlite’查找需要绝对文件名”,即使文件名是未受污染的和绝对的。
(其中大部分来自此处讨论主题)