Back to skill

Security audit

notification-triage

Security checks for vulnerabilities and agentic risk

Overview

This local notification tool is transparent about its design, but it can permanently silence future notifications after one automatic classification, so users should review it carefully before use.

Install only if you are comfortable with a local tool that can permanently change how future notifications are handled. Use `--force` for test classifications, review `rules.json` and `dropped.json` regularly, avoid auto-rules for security, billing, monitoring, or deadline sources, and keep the data directory private. Do not rely on `--dir` until that implementation mismatch is fixed.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T02 · Agent Memory Poisoning

Error
Location
notification-triage.js:98
Finding

Persistent Per-Source Rules Allow Notification Suppression Across Sessions

Content
View full analysis
= 3) level = 'urgent'; else if (score >= 1) level = 'batch'; else level = 'ignore'; // Default rule for this source (unless --force is set, in which case the // classification is a one-off probe and no rule is persisted). if (!rules[source] && !skipAutoRule) { rules[source] = level; saveRules(rules); } return { source, level, rule: 'auto', score }; } ``` ```js if (level === 'ignore') { console.log(`[notify-triage] Ignored: ${source}`); logDropped(source, message); return; } ``` ### Technical Analysis The ...[truncated 2779 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
notification-triage.js:68
Finding

Predictable Temporary Files Permit Symlink-Based Write Redirection

Content
View full analysis
. ``` 4. Each candidate link points to another file writable by the victim process. 5. The victim adds or updates a rule, notification, digest, or seen-state entry. 6. `fs.writeFileSync` ope ...[truncated 928 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The metadata claims destructive operations require --force, but the body documents exceptions like --rules clear, --digest, and --seen --all that mutate persistent state without that safeguard. This mismatch is dangerous because agents or users may rely on the top-level description and invoke commands assuming confirmation-like protection that does not actually exist, causing silent state loss or permanent rule changes.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The metadata claims destructive operations require --force, but the body documents exceptions like --rules clear, --digest, and --seen --all that mutate persistent state without that safeguard. This mismatch is dangerous because agents or users may rely on the top-level description and invoke commands assuming confirmation-like protection that does not actually exist, causing silent state loss or permanent rule changes.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
91% confidence
Finding

The documented behavior allows mutation and clearing of persistent memory-like state (rules.json, seen.json, digest.json, batch state) in ways that can silently alter future agent behavior. Because rules persist indefinitely and ignore can suppress notifications, memory manipulation here can be exploited or accidentally triggered to hide important events over time.

Content

Scanner excerpt · SKILL.md (reported line 34)May include surrounding context.

md
Mitigation: Review `dropped.json` regularly. Any source in `rules.json` at `ignore` level should be re-evaluated periodically.

### 3. Destructive Operations Require `--force`
The following operations are silently destructive — they mutate or clear state without confirmation. To prevent accidental data loss, they require the `--force` flag:

| Operation | Effect | Force Required? |
|-----------|--------|-----------------|

Memory Manipulation

High
Category
Memory Poisoning
Confidence
89% confidence
Finding

The documentation instructs operators to clear state by deleting files under memory/notification-triage/, which is a direct memory/state manipulation pathway outside guarded command flows. In an agent environment, exposing raw file-deletion guidance increases the chance of accidental or unauthorized erasure of audit trails, rules, and queued notifications.

Content

Scanner excerpt · SKILL.md (reported line 53)May include surrounding context.

md
- `dropped.json` — silently-dropped notifications (**capped at 1000 entries**)
- `digest.json` — digest store (**capped at 1000 entries**)

All JSON writes are **atomic** (temp + rename) — a crash mid-write cannot corrupt the state files. Clear state by deleting files under `memory/notification-triage/`.

### 5. Digest vs. Batch — They're Separate
`--digest` clears the `digest.json` store. It does **NOT** clear the `batch.json` queue. To clear the batch queue, flush with `--send` (all pending) or mark items as seen individually.

Persistent Context Injection

Medium
Category
Memory Poisoning
Confidence
95% confidence
Finding

The skill auto-creates persistent per-source rules based on the first classification, and those rules are applied before any future content analysis. Because a single misclassification can permanently force a source into 'ignore', 'batch', or 'urgent', an attacker or malformed first message from a source can poison future handling and silently suppress important notifications or create alert fatigue.

Content

Scanner excerpt · README.md (reported line 124)May include surrounding context.

md
1. **Source-specific rules first** — If a rule exists for the source, use it immediately
2. **Keyword scoring** — Each urgent keyword +2, each batch keyword -1, time-sensitive +1
3. **Thresholds** — Score ≥ 3 = urgent, Score ≥ 1 = batch, else ignore
4. **Auto-rule creation** — First classification for a source saves its level as a persistent rule

---

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill advertises environment-based configuration via NOTIFY_TRIAGE_DIR but declares no explicit tool scope or permissions boundary. In an agent setting, undeclared environment access weakens operator visibility into what inputs influence behavior and where persistent state may be written, which can enable unexpected data access or persistence outside the default directory.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The skill explicitly supports autonomous state-changing decisions such as silent dropping, digest clearing, and persistent rule creation, some without confirmation. In this context, autonomous handling of notifications is particularly risky because a single misclassification can permanently suppress future alerts from a source, including security-relevant ones.

Content

Scanner excerpt · SKILL.md (reported line 34)May include surrounding context.

md
Mitigation: Review `dropped.json` regularly. Any source in `rules.json` at `ignore` level should be re-evaluated periodically.

### 3. Destructive Operations Require `--force`
The following operations are silently destructive — they mutate or clear state without confirmation. To prevent accidental data loss, they require the `--force` flag:

| Operation | Effect | Force Required? |
|-----------|--------|-----------------|

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI contract states destructive operations require --force, but clearAllRules() is reachable from the rules clear path without any force check. In this skill, rules are persistent and first classification auto-creates durable behavior, so clearing rules can silently wipe operator-established policy and change future notification handling in a lasting way.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file documents that notification data is stored under memory/notification-triage/, including pending queues, rules, seen IDs, and digest entries. Because notifications may contain sensitive content, the skill description should explicitly disclose that user or system notification data is persisted locally and may remain on disk until cleared.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The README frames the skill as handling 'every notification' and says it 'fixes this with one tool,' but it does not define specific activation phrases, contexts, or exclusions. In a markdown skill description, this kind of broad positioning can create ambiguous invocation scope and increase the chance of unintended use.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation claims '--dir ' overrides the data directory, but although the CLI parses this option into rootDir, that value is never applied when computing WORKSPACE or DATA_DIR. As a result, the documented behavior is contradicted by implementation and users cannot redirect storage via the flag.

Content

No source excerpt is available for this finding.