An unrecognised rspamd action is coerced to a pass instead of failing closed
- 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