Skip to content
Code Recycle

Component · for humans & their agents

Inbox Rule Tripwire

verified · first-partyactively maintained$0 during beta (was $59)

The rule an account takeover leaves behind — without flagging every user who files newsletters. Grades inbox rules by severity so a reviewer can triage instead of reading three hundred equal-looking rows.

by Code Recycle

Get it free — beta

Every claim on this page is refundable if it is untrue — refund policy.

24 tests · 3/3 deliberate defects caught. Zero runtime dependencies. Provider-neutral.

Why the rule, and not the login

Someone gets into a mailbox. Before doing anything noisy they create an inbox rule, because a rule outlives the session: it keeps working after the password is changed, it runs server-side whether or not anyone is logged in, and almost nobody ever opens the rule list.

Three shapes cover most of it:

  • Forward externally — the attacker keeps reading mail they no longer have access to.
  • Delete or hide anything matching "invoice", "wire", "payment" — the victim never sees the
  • supplier chasing an invoice that was already redirected, and the fraud stays quiet long enough
  • to clear.
  • Mark as read and move to RSS Feeds / Conversation History / Notes — mail still arrives, so
  • nothing looks broken. It simply never appears in the inbox.

An IMAP scanner cannot see any of this; server-side rules are not messages.

The property that decides whether anyone keeps it switched on

Precision. Ordinary users have rules — filing newsletters, sorting by project, moving CC'd threads — so a detector that flags every rule with a moveToFolder action flags all of them. It gets muted inside a week, and a muted detector is worse than none, because its silence reads as coverage.

  gradeRule({ displayName: "Newsletters", actions: { moveToFolder: "Reading", markAsRead: true } });
  // severity: "none"   ← this is what rules are for
  
  gradeRule({
    displayName: "..",
    conditions: { subjectContains: ["invoice", "wire transfer"] },
    actions: { moveToFolder: "RSS Feeds", markAsRead: true },
  });
  // severity: "critical"  ← hides financial mail in a folder nobody opens

Same action, opposite verdict. The signal is the combination — hiding folder, plus concealment, plus finance vocabulary — never any one of them alone.

Severity ladder

| severity | when | |---|---| | critical | forwards outside the organisation | | critical | destroys or hides mail and targets finance vocabulary | | high | permanently deletes (bypasses Deleted Items — unrecoverable) | | high | marks read and hides, without finance targeting | | low | internal forward; finance words alone; an unnamed acting rule | | none | files mail into an ordinary folder |

internalDomains matches on a dot. notacme.com ends with acme.com and belongs to someone else — under endsWith, an attacker forwards to a domain registered to end in yours and the exfiltration is graded as an internal forward. Leaving internalDomains unset does not silence anything: every forward is then treated as external.

Disabled rules are still reported, at full severity, marked disabled: true. A disabled malicious rule means somebody got in and set it up; attackers toggle rules off after a run. Marked so a reviewer can de-prioritise, not filtered so nobody sees it.

What it does not do

| not included | why | |---|---| | Talking to Microsoft Graph / Gmail | you fetch; this grades. Keeps it provider-neutral and testable | | Deleting or disabling rules | a detector that mutates mailboxes is a different risk conversation | | Detecting the login that created the rule | signin-spray-shape | | Scanning message content | mailbox-takeover-tripwire | | Suppressing repeat alerts | findings-delta |

Normalise your provider's rules into InboxRule and the same grading runs over Graph messageRules, Gmail filters, or a JMAP rule set.

On the word lists

FINANCE_TERMS and HIDING_FOLDERS are exported, extensible, and deliberately generic. No bank or counterparty names ship in them — a hardcoded list of institutions turns the source file into a description of who you bank with, readable by whoever holds the alert. A test asserts the list stays clean of them. Add your own vocabulary at the call site:

  gradeRule(rule, { internalDomains: ["acme.com"], financeTerms: ["PO-", "netsuite"] });

Like any keyword layer this is evadable — a rule matching on sender rather than subject will not trip the finance check. The structural signals (external forward, permanent delete, hiding folder) do not depend on vocabulary, which is why they carry the severity.

01Capabilities

Does

  • + Security monitoring
  • + Security triage
  • + Data exposure boundary

Doesn’t

  • No exclusions declared

02Requirements & stack

Depends on

No declared dependencies

Credentials needed

None declared

Stack

03Community

No endorsements yet

No verified confirmations yet — be the first.

Confirmations come from verified purchasers, installers, vetted reviewers, or an installation outcome your org reported through the agent tools. They grade quality — security is verified separately, and community votes can never override the security gate.

Open an issue

Sign in to confirm — weight comes from verified usage, not vote count.

Nobody has reported anything yet — a success counts as a report too.

04Trust Passport

Full passport →
–/100

0/0 automated components pass. An automated score is never a security guarantee.

✓ Verified · first-partyreviewed Sep 20, 2026 · re-verification due Dec 19, 2026
  • publisher identity Publisher status verified; 1 verification(s) on file
  • malicious pattern scan No known malicious-behavior patterns across 7 source file(s) plus listing text
  • capability contract All 0 observed capability reference(s) match the declared manifest
  • agent safety scan No injection patterns in agent-readable content
  • provenance No release signature or provenance attestation
  • behavioral sandbox Not performed in this environment — requires the production isolated runner (docs/sandbox-requirements.md). No untrusted code is ever executed on the application host.

Every listing must pass this review before it can be sold, and it is re-run on every release. Verification describes what we checked — it is not a guarantee that the software is safe.

VersionChannelReleasedNotes
0.1.0stableAug 12, 2026Initial extraction.