Body_checks: How to filter base64 encoded content

emailhtmllinuxpostfixspam-filter

The idiomatic answer is probably "don't – use a filter that decodes the message first", but as can be seen in the second answer to that question, it should also be possible with body_checks which is also what the BUILTIN_FILTER_README @ postfix.org says – and that's what I'd like to do.

Here's one that's been bugging me for quite some time:

--===============6489786132958404869==
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

SmFnIGhhciByZWRhbiBza3Jpdml0IHRpbGwgZGlnLCBtZW4gZHUgc3ZhcmFyIG1pZyBpbnRlLiBM
w6V0IG1pZyB2ZXRhLCBqYWcgaGFyIG7DpWdyYSBzYWtlciBhdHQgYmVyw6R0dGEuIEtvbnRha3Rh
IG1pZyBpIG1pbiBwcml2YXRhIGUtcG9zdDogaXJlbmUub3NiZXJnNzNAZ21haWwuY29tCg==

--===============6489786132958404869==--

For this, I've added the body_checks rule:

/SmFnIGhhciByZWRhbiBza3Jpdml0IHRpbGwgZGlnLCBtZW4gZHUgc3ZhcmFyIG1pZyBpbnRl/ REJECT Spam

but it just won't catch it when it's in such a block. It caught one attempted delivery when the same string was embedded in an body:
<div dir="ltr"><pre class="gmail-moz-quote-pre"><pre>SmFnIHZpbGwgcHJhdGEgbWVkIGRpZywgbWVuIGRldCBmaW5ucyBmw7ZyIG3DpW5nYSBtZWRkZWxh</pre> but that's the only time the rule has successfully caught this. I have added quite a few of these base64 encoded rules but none of them catch anything when embedded like above.

The base64 encoding in this particular case is always exactly the same, so I don't have to make a base64 tripple to catch variants, which I've done for other cases:

/aHR0cHM6Ly9jbGNrLnJ1|dHRwczovL2NsY2sucnUv|dHBzOi8vY2xjay5y/ REJECT Please remove the link to clck.ru

The above doesn't catch anything when embedded in a block like above either.

I've tried adding the main.cf setting

disable_mime_input_processing = yes

which seems to have improved things. It catches some of them now, but not all those than I can manually verify should catch messages that slips though the cracks.

Any idea why this doesn't work and what I can do about it? I'm using 3.6.4-1.fc35.

Best Answer

There is a builtin feature for diagnosing postfix map lookups, specifically for body_checks as well. Pass the same map configuration you configured for your smtpd cleanup service to the postmap utility and add one or more -v for detailed output:

# postconf body_checks
body_checks=pcre:/etc/postfix/body.pcre
# cat known_bad.eml | postmap -v -b -q - pcre:/etc/postfix/body.pcre
...
postmap: dict_pcre_lookup: body.pcre: test line 1
postmap: dict_pcre_lookup: body.pcre: test line 2
postmap: dict_pcre_lookup: body.pcre: test line 3
test line 3 DUNNO

This will tell you, for each body line, which (if any) entry in your map matched against your line.

One possible reason your map might not behave the way you expect it to would be a too-broad match with DUNNO result preceding your intended REJECT spam result, instructing the cleanup server to proceed with the next line instead of trying further expressions.