codingjoe / codingjoe/relay

An unrecognised rspamd action is coerced to a pass instead of failing closed

Open Beginner friendly
#234 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
4
Forks
0
Avg merge
8h 24m
Merged PRs (30d)
115

Description

Found by testJoe and tagged by lazyJoe during the ClamAV work on #184 (`codingjoe-turbo-spoon`). Pre-existing on `main`, not introduced by that PR.

lazyJoe defer line: `defer: delete the \`except ValueError\` fallback in \`SpamResult.from_response\`; rspamd 4.1 under relay's pinned config emits only the six enumerated actions, so mapping an unknown action to \`NO_ACTION\` records a new scanner state as a pass instead of failing closed like the \`symbols\` check at L60. [services/email/spam/client.py:42]`

## What

```python
try:
action = SpamAction(data.get("action", "no action"))
except ValueError:
action = SpamAction.NO_ACTION
```

Under the pinned `rspamd/rspamd:4.1` with the mounted `local.d` config, the six members of `SpamAction` are the entire vocabulary. So the fallback cannot fire today.

The problem is the direction it fails in. If rspamd ever grows an action — `discard`, `quarantine`, or a custom action — this coerces it to `NO_ACTION`, which the scan tasks read as a pass. A verdict that should suppress the message is delivered instead.

## Why removal is the fix

Deleting the `try`/`except` leaves `action = SpamAction(data.get("action", "no action"))`, three lines shorter. An unknown action then raises, the scan task retries, and the message fails closed. When rspamd really does grow an action, the fix is to add the enum member; `message/models.py` already absorbs extra values through `spam_badge_variant` and the model choices.

Failing closed is the same contract `check_message` re-established by keying its retry on the `CLAM_VIRUS_FAIL` symbol rather than on the `soft reject` action.

## Note

Related but separate: `SpamAction` has no member for `discard` or `quarantine`, and `force_actions` could set either. Whoever picks this up should decide whether the enum grows or the client keeps failing closed on the unknown.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading services/email/spam/client.py around line 42, especially SpamResult.from_response and the symbols check at L60. Confirm that an unrecognised rspamd action raises rather than becoming NO_ACTION, and verify that the existing spam-scan behavior still passes its tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.