T09 · Insecure Skill Coding Practices
- Location
scripts/cn_todo_today.py:24- Finding
Todo Data File Is Created Without Restrictive Permissions or Symlink Protection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/cn_todo_today.py, lines 24-26
Vulnerability Type: Insecure local file creation and symbolic-link following
Risk Level: Lowpython with open(TODO_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2)Technical Analysis
The application stores todo data in the fixed path
~/.cn_todo_today.jsonusing the standardopen()function without explicitly applying restrictive permissions. The permissions assigned to a newly created file therefore depend on the process umask. Under a commonly used umask of022, the file can be created with mode0644, allowing other local users to read its contents when directory permissions permit traversal.The operation also follows symbolic links. If an attacker can manipulate the target path before the application saves data, the attacker can replace
~/.cn_todo_today.jsonwith a symbolic link to another file writable by the invoking user. A subsequent save will truncate that target and replace its contents with JSON data.The implementation does not use exclusive creation, a no-follow option, atomic replacement, or validation that the destination is a regular file owned by the current user.
Attack Path
Information disclosure path:
- The user runs an operation that invokes
save_todos(). - The application creates
~/.cn_todo_today.jsonwith permissions derived from the current umask. - If those permissions allow local reads and the home directory is traversable, another local user reads the file.
- Todo descriptions and their creation or completion timestamps are disclosed.
Symbolic-link overwrite path:
- An attacker with the ability to manipulate
~/.cn_todo_today.jsonremoves or renames the existing file. - The attacker creates a symbolic link at that path pointing to another file writable by the victim user.
- The victim invokes an operation that sa ...[truncated 930 chars]
- The user runs an operation that invokes
- Remediation
View remediation
Remediation Suggestions
- Create the data file with owner-only permissions (
0600) rather than relying on the process umask. - Write updates to a securely created temporary file in the same directory and atomically replace the destination with
os.replace(). - Create the temporary file using
tempfile.mkstemp()ortempfile.NamedTemporaryFile()with restrictive permissions. - Reject symbolic links by using
os.open()withO_NOFOLLOWwhere supported and verify withos.fstat()that the opened object is a regular file. - Verify that an existing destination is owned by the current user before replacing it.
- Flush buffered data and call
os.fsync()before atomic replacement when durability is required. - Apply
os.chmod(TODO_FILE, 0o600)to securely migrate an existing regular data file, after validating its ownership and type.
- Create the data file with owner-only permissions (
