Back to skill

Security audit

noise-nuisance-log

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local noise-incident logger whose file writes and complaint-letter generation match its stated purpose, though users should treat the saved records as private sensitive data.

Install only if you are comfortable keeping noise-dispute records on this machine. Avoid putting names, addresses, phone numbers, or sensitive allegations in notes unless needed, keep ~/.noise-log.json and exports out of shared or synced folders, and review complaint letters before sending.

Vulnerability Patterns
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/noise_log.py:28
Finding

Sensitive records are written without restrictive permissions or symlink protections

Content
View full analysis

Vulnerability Details

File Locations:

  • scripts/noise_log.py:28-29
  • scripts/noise_log.py:199-205
  • scripts/noise_log.py:303-306

Vulnerability Type: Insecure file creation, plaintext sensitive-data exposure, and symlink-following overwrite
Risk Level: Medium

Vulnerable Code

scripts/noise_log.py:28-29:

python
def save(db, path):
    json.dump(db, open(path, "w"), indent=2)

scripts/noise_log.py:199-205:

python
fields = ["start", "weekday", "hour", "duration_min", "type", "loudness",
          "impact", "neighbor", "note"]
with open(a.csv, "w", newline="") as f:
    w = csv.DictWriter(f, fieldnames=fields)
    w.writeheader()
    for i in incs:
        w.writerow({k: i.get(k, "") for k in fields})

scripts/noise_log.py:303-306:

python
out = os.path.join(os.path.dirname(a.file) or ".", f"noise-complaint-{a.to}.txt")
with open(out, "w") as f:
    f.write(body)
print(f"\n[saved to {out} — review and edit before sending]", file=sys.stderr)

Technical Analysis

The application stores noise-incident records, CSV exports, and generated complaint letters as plaintext files using ordinary open(..., "w") calls. It does not explicitly apply owner-only permissions such as 0600; therefore, the resulting permissions depend on the process umask. Under a permissive configuration, other local users may be able to read these files.

The records may include names, residential addresses, phone numbers, neighbor or unit identifiers, household impacts, incident notes, and allegations about responsible parties. This makes the files privacy-sensitive even though no credentials are stored.

The write operations also follow symbolic links and silently truncate existing files. The complaint-letter filename is predictable, such as noise-complaint-landlord.txt. If the selected directory is shared or attacker-controlled, a local attacker can pre-create that file ...[truncated 1848 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create private data files atomically with owner-only permissions:

    • Use os.open() with os.O_WRONLY | os.O_CREAT | os.O_TRUNC and mode 0o600.
    • For new destinations that must not exist, add os.O_EXCL.
    • Wrap the descriptor with os.fdopen() and always use a context manager.
  2. Prevent symbolic-link attacks:

    • Add os.O_NOFOLLOW where supported.
    • Inspect destinations with os.lstat() and reject symbolic links.
    • Do not perform a separate check followed by an ordinary open(), because that introduces a time-of-check/time-of-use race.
    • Prefer atomic creation in a trusted, user-owned directory.
  3. Avoid silent overwrites:

    • Require an explicit overwrite option for existing exports and letters.
    • Otherwise, use exclusive creation or generate a unique filename.
    • If replacement is required, write to a private temporary file in the same directory and atomically replace the destination after validation.
  4. Harden existing storage:

    • Apply os.chmod(path, 0o600) to existing user data files after verifying that the path is a regular file and not a symbolic link.
    • Verify that the parent directory is owned by the expected user and is not writable by untrusted accounts.
  5. Improve resource handling:

    • Replace json.load(open(path)) and json.dump(..., open(path, "w")) with explicit with blocks to guarantee prompt file closure and reliable error handling.
  6. Document that JSON logs, CSV exports, and complaint letters contain sensitive personal and allegation data, and advise users not to place them in shared directories.

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code largely matches the declared purpose: it logs recurring noise incidents, stores timestamps/duration/type, analyzes time-of-day and weekday patterns, flags typical quiet hours, computes a severity-like score, and generates complaint letters. However, there are material discrepancies. First, the description says it records a decibel estimate, but the implementation only accepts qualitative loudness labels ('faint', 'moderate', 'loud', 'very loud') and never stores or computes decibel values. Second, the description says it flags violations of municipal limits, but the code only flags incidents occurring during configurable night hours; there is no ordinance database, threshold-by-decibel logic, or municipal-limit enforcement beyond a comment about common defaults. Third, the code has an extra CSV export feature not mentioned in the description. The first two differences are substantive enough to count as a description/behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises commands that write persistent data to a local file (~/.noise-log.json) and export CSV, but it declares no explicit tool scope or permissions. In an agent environment, undeclared file-write capability weakens user consent and policy enforcement because the agent can persist sensitive complaint notes and personal details without a clear capability boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code stores potentially sensitive details such as impact notes, neighbor identifiers, and free-form notes in a local JSON file under the user's home directory. Although the module docstring mentions the storage location, it does not warn users that personal data they enter will be persisted locally, which is the kind of user disclosure required for data-affecting file writes in code files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The export command writes all logged incidents to a CSV file, including fields like impact, neighbor, and note, which may contain sensitive personal information. While it prints that export occurred, there is no warning beforehand or descriptive disclosure that the export includes these potentially sensitive fields and creates a shareable plaintext file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill stores incident notes, addresses, names, neighbor identifiers, and complaint-letter content in a local log file without a prominent privacy warning. If the device is shared, backed up, synced, or later inspected, these records can expose sensitive interpersonal disputes and personally identifiable information, increasing retaliation or privacy risks.

Content

No source excerpt is available for this finding.