T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/init.py:84
- Finding
- Arbitrary File Deletion Through CASHBOOK_DB and Forced Initialization## Vulnerability Details **File Location**: `scripts/init.py:84-89`, with attacker-controlled path resolution in `scripts/db.py:9-12` **Vulnerability Type**: Arbitrary file deletion **Risk Level**: High ### Technical Analysis The database path is accepted directly from the `CASHBOOK_DB` environment variable without restriction, canonicalization, ownership validation, or verification that the target is a cashbook SQLite database: ```python def get_db_path(): """Return the database path, preferring CASHBOOK_DB.""" return os.environ.get("CASHBOOK_DB", os.path.expanduser("~/.local/share/cashbook/cashbook.db")) ``` Forced initialization deletes whatever filesystem object exists at that path before attempting to create a database: ```python def init_db(force=False): db_path = get_db_path() if force and os.path.exists(db_path): os.remove(db_path) print(f"Deleted old database: {db_path}") ``` The `--force` option is exposed without an interactive confirmation or a check that the path is within the normal cashbook data directory: ```python def main(): parser = argparse.ArgumentParser(description="Initialize cashbook database") parser.add_argument("--force", action="store_true", help="Delete and recreate database") args = parser.parse_args() init_db(force=args.force) ``` Consequently, any actor able to influence the environment and cause the initialization command to run with `--force` can select an arbitrary file writable by the process and delete it. The deletion occurs before SQLite validates the target, so the file does not need to be a database. This is especially relevant in an agent environment, where tool instructions or user-supplied command parameters may influence environment variables and command invocation. ### Attack Path 1. The attacker identifies a file writable by the user running the skill, such as a document ...[truncated 1266 chars]
- Remediation
- ## Remediation Suggestions - Do not pass the unrestricted `CASHBOOK_DB` value directly to a destructive operation. - Resolve the path with `os.path.realpath()` and, by default, require it to remain under a dedicated directory such as `~/.local/share/cashbook/`. - If custom database paths must be supported, separate database selection from database deletion. Require an explicit, independently supplied confirmation of the canonical path. - Before deletion, verify that the target is a regular file, is not a symbolic link, is owned by the current user, contains a valid SQLite header, and has the expected cashbook schema or application marker. - Refuse special files, directories, and paths outside an approved storage boundary. - Create a timestamped backup before resetting an existing database. - Require interactive confirmation unless a separately protected administrative automation mode is explicitly enabled. - Prefer clearing known cashbook tables inside a validated database rather than deleting an arbitrary path.
