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.
