Back to skill

Security audit

noise-nuisance-log

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local noise-incident logger with some privacy and accuracy caveats, but I did not find hidden execution, data exfiltration, or purpose-mismatched behavior.

Before installing, understand that this keeps dispute-related records on disk in plain files and can include your address, phone number, neighbor identifiers, and sensitive notes. Store the log in a private directory, review CSVs and letters before sharing, and treat municipal-limit and decibel language as general context unless you separately verify local law and calibrated measurements.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/noise_log.py:28
Finding
Sensitive incident records are written without restrictive permissions or symbolic-link protection## Vulnerability Details **File Location**: `scripts/noise_log.py:28-34` **Vulnerability Type**: Insecure sensitive-file handling and predictable file write **Risk Level**: Medium ```python def load(path): if os.path.exists(path): return json.load(open(path)) return {"incidents": []} def save(db, path): json.dump(db, open(path, "w"), indent=2) ``` ### Technical Analysis The incident database can contain privacy-sensitive information, including timestamps, a neighbor or unit identifier, incident notes, and details about sleep or household impacts. The `save` function opens the configured path with Python's default write behavior. New-file permissions therefore depend on the process umask rather than being explicitly restricted to the owner. On a system with a permissive umask, other local users may be able to read the database. The operation also follows symbolic links and truncates an existing target before writing. It does not verify that the destination is a regular file owned by the current user. Because `--file` can select a custom path and the default filename is predictable, an attacker with write access to the containing directory could prepare a symbolic link that redirects the operation to another file writable by the victim. The write is also non-atomic, so interruption can leave a partially written or corrupted database. ### Attack Path 1. The attacker obtains write access to the directory containing the selected incident database. 2. The attacker predicts the database filename or learns the value supplied through `--file`. 3. The attacker creates that path as a symbolic link to another file that the victim can modify. 4. The victim invokes the `log` command. 5. `save()` follows the symbolic link, opens the target in `"w"` mode, and immediately truncates it. 6. The JSON incident database is written into the redirected target. Alternatively, where no symbolic link is involved but ...[truncated 771 chars]
Remediation
## Remediation Suggestions - Create the database with owner-only permissions, such as mode `0o600`. - Use `os.open()` with `O_NOFOLLOW` where supported and reject destinations that are symbolic links or non-regular files. - Verify the ownership and mode of an existing database before updating it. - Write the JSON to a securely created temporary file in the same directory, flush it with `fsync()`, set mode `0o600`, and atomically replace the destination with `os.replace()`. - Ensure the containing directory is private and not writable by untrusted users. - Use context managers for every opened file so descriptors are reliably closed.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/noise_log.py:286
Finding
Complaint letters are saved to predictable files using unsafe write semantics## Vulnerability Details **File Location**: `scripts/noise_log.py:286-289` **Vulnerability Type**: Predictable sensitive-file write and symbolic-link overwrite **Risk Level**: Medium ```python body = LETTER_TEMPLATES[a.to].format(**ctx) print(body) 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 Generated complaint letters can contain the user's name, residential address, phone number, incident statistics, and dispute details. The output filename is fixed according to the recipient type, such as `noise-complaint-landlord.txt`, and is placed in the incident database directory. The file is opened with `"w"` without owner-only permissions, exclusive creation, symbolic-link rejection, destination validation, or atomic replacement. Consequently, its confidentiality depends on the process umask. The predictable filename also permits a local attacker with write access to the destination directory to create a symbolic link before generation. Opening a symbolic link in `"w"` mode follows the link and truncates its target. The generated letter is then written into that target under the victim's existing permissions. ### Attack Path 1. The attacker gains write access to the directory containing the incident database or the current directory when applicable. 2. The attacker predicts the output name from the selected recipient type. 3. For example, the attacker creates `noise-complaint-landlord.txt` as a symbolic link to another file writable by the victim. 4. The victim runs `letter --to landlord`. 5. The application follows the symbolic link and truncates the linked file. 6. The complaint letter replaces the previous target contents. 7. If the resulting file permissions are permissive, other local users may also read ...[truncated 701 chars]
Remediation
## Remediation Suggestions - Allow the user to provide an explicit output path or create a unique output filename securely. - Create complaint files with owner-only mode `0o600`. - Reject symbolic links and non-regular destinations, using `O_NOFOLLOW` where available. - If overwriting is intended, validate ownership and use a securely created same-directory temporary file followed by atomic replacement. - If overwriting is not intended, use exclusive creation so an existing path causes the operation to fail safely. - Warn users before saving personally identifiable information into shared directories.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/noise_log.py:181
Finding
Untrusted incident fields are exported without spreadsheet formula neutralization## Vulnerability Details **File Location**: `scripts/noise_log.py:181-193` **Vulnerability Type**: CSV formula injection **Risk Level**: Low ```python def cmd_export(a): incs = load(a.file)["incidents"] if not incs: print("(nothing to export)") return 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}) print(f"exported {len(incs)} incidents → {a.csv}") ``` ### Technical Analysis The `impact`, `neighbor`, and `note` fields can contain user-controlled text. These values are passed directly to `csv.DictWriter`. CSV quoting preserves file structure but does not prevent spreadsheet programs from interpreting cells beginning with characters such as `=`, `+`, `-`, or `@` as formulas. If a malicious value reaches the JSON database—through direct editing, a shared or imported database, or untrusted text copied into a logging command—the export preserves the formula. Opening that CSV in a spreadsheet application that evaluates formulas may trigger calculations or external-data functions. Actual behavior depends on the spreadsheet application, its security settings, and whether the user approves any prompts. The Python program itself does not execute the formula. ### Attack Path 1. An attacker causes a crafted value such as a formula-leading string to be stored in `impact`, `neighbor`, or `note`. 2. The victim runs the `export` command. 3. The application writes the crafted cell verbatim into the CSV file. 4. The victim opens the CSV with a spreadsheet application that treats the cell as a formula. 5. The spreadsheet evaluates the expression, subject to its security controls. 6. Depending on supported functions and pol ...[truncated 669 chars]
Remediation
## Remediation Suggestions - Neutralize text cells that begin with `=`, `+`, `-`, `@`, tab, carriage return, or other spreadsheet-recognized formula prefixes. - A common defensive approach is to prefix such values with an apostrophe before writing them. - Apply neutralization only to textual fields so numeric fields retain their intended types. - Provide an explicit spreadsheet-safe export mode and make it the default. - Document that raw CSV exports should be imported as text when exact, unmodified evidence is required. - Add tests covering formula prefixes, leading whitespace, tabs, embedded delimiters, quotes, and line breaks.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This is a mismatch because the code does not fully implement key parts of the declared description and also includes notable capabilities not mentioned. Most importantly, it does not record actual decibel estimates or measure sound levels; instead it records qualitative loudness bands (faint/moderate/loud/very loud). It also does not check municipal noise limits beyond generic user-configurable night hours, so the claim that it flags violations of municipal limits is overstated. While the core purpose broadly aligns—building a documented noise record, analyzing patterns, scoring severity, and generating complaint letters—the description is not an accurate representation of the code's actual behavior.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest says each incident is timestamped with a decibel estimate and that the skill flags violations of municipal limits. In the implementation, incidents store only a categorical loudness value from LOUDNESS_BANDS, and the only violation logic uses configurable quiet hours; there is no decibel field, threshold comparison, or municipality-specific limits analysis anywhere in the code.

Description-Behavior Mismatch

Low
Confidence
83% confidence
Finding
The generated letters can still contain placeholders such as "[your name]", "[phone]", and "[describe the source]" when inputs are missing, and the program explicitly warns the user to review and edit before sending. That behavior is closer to producing a draft than a fully ready-to-send complaint letter.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The markdown file says the skill stores logs locally as JSON and exports CSV for mediators or attorneys, and earlier lines note optional neighbor/unit identifiers and personal impact notes. That behavior can affect user privacy and third-party personal data, but the README provides no warning or guidance about handling, sharing, or protecting this information.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The markdown explicitly states that the log is stored at `~/.noise-log.json`, and the examples show users entering personal addresses, names, notes, and neighbor/source details. However, the skill description does not warn users that this local file may contain sensitive personal or dispute-related information and should be protected or reviewed before sharing/exporting.

Scope Creep

Low
Category
Excessive Agency
Content
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Static analysis

No suspicious patterns detected.