T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/sanitize.py:484
- Finding
- Raw PII Is Written to a Predictable Sidecar File Without Secure File Controls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sanitize.py`, lines 484–498 **Vulnerability Type**: Plaintext sensitive-data storage and unsafe predictable file creation **Risk Level**: Medium ### Vulnerable Code ```python map_path = args.output.with_suffix(".entity-map.json") map_data = { "entity_map": result.entity_map, "entities": [ { "category": e.category.value, "text": e.text, "start": e.start, "end": e.end, } for e in result.entities ], } map_path.parent.mkdir(parents=True, exist_ok=True) map_path.write_text(json.dumps(map_data, indent=2), encoding="utf-8") ``` ### Technical Analysis When `--json` and `--output` are used together, the application automatically creates a predictably named `*.entity-map.json` sidecar. This file contains the original values of all detected PII, including credentials, financial identifiers, medical identifiers, and personal data. `Path.write_text()` does not enforce owner-only permissions. The resulting permissions depend on the process umask and may permit access by other local users or services. The file also remains on disk without any retention or secure-deletion policy. The predictable path introduces an additional local symlink risk. If an attacker can write to the selected output directory, they may pre-create the sidecar path as a symbolic link. `Path.write_text()` follows an existing symlink, allowing the invoking user to overwrite a symlink target to which that user has write access. The written content will also contain sensitive PII. Instructions telling the AI agent not to read the sidecar do not provide operating-system-level confidentiality or integrity protection. ### Attack Path 1. The user invokes the documented JSON workflow with an output path, such as: ```bash python scripts/sanitize.py sensitive.txt --json --output clean.txt ``` 2. The application derives the predictable sidecar path `cl ...[truncated 1415 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not create a raw entity map automatically when `--json` and `--output` are combined. Require a separate, explicit option such as `--write-entity-map`. 2. Clearly warn that the sidecar contains plaintext sensitive data and require confirmation or explicit noninteractive consent. 3. Create the file with owner-only permissions (`0600`) using a low-level API such as `os.open()` rather than relying on the process umask. 4. Use exclusive creation (`O_CREAT | O_EXCL`) and, where supported, `O_NOFOLLOW` to reject existing files and symbolic links. 5. Validate that the destination is a regular file and that its parent directory is trusted and not writable by untrusted principals. 6. Write through a securely created temporary file, flush and synchronize it as appropriate, and perform a carefully validated atomic placement operation. 7. Avoid storing raw entity values entirely when reversible mappings are unnecessary. If reversibility is required, consider authenticated encryption with externally managed keys. 8. Document retention requirements and provide an explicit cleanup mechanism. Users should be advised not to place entity maps in shared, synchronized, indexed, or routinely backed-up locations. ]]>
