Issue Description
The official spam filter rules (spam-filter v3.0.1, imported into Stalwart 0.16.22) define the DNSBL server STWT_SURBL_DOMAIN with tag expressions that compare the last octet of the SURBL MULTI answer for equality with 128, 64, 32, 16, 8, 4 and 1.
SURBL documents MULTI as a bitmasked list (page “Lists” on the SURBL site): an entry on several lists returns the sum of their values in the last octet; their own example is 127.0.0.80 = MW (16) + ABUSE (64). None of the equality branches matches such a sum, so a domain listed in two or more SURBL categories receives no SURBL tag and no score, although the lookup succeeded. The stronger a listing is, the more likely the rule is to ignore it.
The same comparison shape is used in STWT_SURBL_HASHBL_DOMAIN (same bit values per SURBL) and STWT_URIBL_DOMAIN; for URIBL the provider states that combined values should not occur outside its test points, so the practical impact is on SURBL MULTI.
Expected Behavior
A response whose last octet combines several SURBL lists is tagged. Keeping one tag per lookup and the existing branch order, replacing the equalities with >= selects the highest-priority category present:
octets[3] >= 128 → CRACKED_SURBL
octets[3] >= 64 → ABUSE_SURBL
octets[3] >= 32 → CT_SURBL
octets[3] >= 16 → MW_SURBL_MULTI
octets[3] >= 8 → PH_SURBL_MULTI
octets[3] >= 4 → DM_SURBL
octets[3] == 1 → SURBL_BLOCKED
With this, 127.0.0.80 yields ABUSE_SURBL and 127.0.0.254 yields CRACKED_SURBL; single-list answers keep their current tag.
Actual Behavior
A combined answer (e.g. 127.0.0.80, or 127.0.0.254 from SURBL’s permanent test point) matches no branch, the expression falls through to else = false, and the message gets no SURBL tag.
Reproduction Steps
- Import the official spam filter rules v3.0.1 (default configuration).
- Confirm the resolver returns a combined value for SURBL’s permanent test point (command and output in the log section below): 127.0.0.254.
- Deliver a message whose body contains a link to that test-point domain and read its X-Spam-Result header.
- No *_SURBL tag is present, although the DNSBL lookup succeeded with 127.0.0.254.
Relevant Log Output
$ dig +short surbl-org-permanent-test-point.com.multi.surbl.org
127.0.0.254
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
Additional Context
Rule source: file rules/dnsbl.toml in the stalwartlabs/spam-filter repository, tag v3.0.1, object STWT_SURBL_DOMAIN; the rules on main are identical. Stalwart evaluates the tag expression on the first A record of the answer and returns one tag (crates/spam-filter/src/modules/dnsbl.rs in the stalwart repository), so the fix belongs in the rules, not in the server.
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on