T09 · Insecure Skill Coding Practices
- Location
scripts/ms_todo_auth.py:99- Finding
OAuth Tokens Stored Without Explicit Owner-Only File Permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ms_todo_auth.py, lines 99–101
Vulnerability Type: Insecure storage of OAuth access and refresh tokens
Risk Level: MediumVulnerable Code
python def write_json(path: Path, payload: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")This function is used to persist complete OAuth responses in the following flows:
python write_and_print_json(TOKEN_FILE, payload, redact_tokens=True)Although token values are redacted from normal console output, the complete payload—including access tokens, refresh tokens, and potentially ID tokens—is written to
token.json.Technical Analysis
The configuration directory and token file are created without explicit owner-only permissions. Their effective permissions therefore depend on the process umask and any pre-existing filesystem objects. Under a permissive umask or unsafe configuration-directory override, another local account may be able to read the token file.
The destination can also be controlled through environment variables such as
MS_TODO_CONFIG_DIRandMS_TODO_TOKEN_FILE. The implementation does not verify destination ownership, permissions, or whether the destination is a symbolic link. It also does not use an atomic, exclusive file-creation operation. These omissions increase the risk when the helper runs in a shared or adversarial local environment.The network transmission detected by the pre-scan is otherwise consistent with the declared functionality: device codes and refresh tokens are sent to Microsoft OAuth endpoints under
login.microsoftonline.com. The requestedTasks.ReadWritepermission is necessary for the documented task creation, modification, completion, and deletion features, whileoffline_accesssupports the documented token-refresh feature.Attack Path
- A victim runs
device-codefollowed by `poll-tok ...[truncated 1520 chars]
- A victim runs
- Remediation
View remediation
Remediation Suggestions
- Create the configuration directory with owner-only permissions (
0700on POSIX systems), and verify that existing directories are owned by the current user and are not writable by untrusted users. - Create token and device-code files with owner-only permissions (
0600on POSIX systems) rather than relying on the process umask. - Write secrets atomically:
- Create a temporary file in the same trusted directory using exclusive creation.
- Apply restrictive permissions before writing sensitive content.
- Flush and securely replace the destination.
- Reject symbolic links and other unexpected file types for secret destinations. Where supported, use no-follow semantics during file creation.
- Validate environment-overridden paths before storing credentials. Warn or fail if the destination is in a shared, world-readable, or world-writable directory.
- On Windows, apply an ACL that grants access only to the current user rather than relying solely on generic file-creation behavior.
- Prefer an OS-native credential store or keychain for refresh tokens when practical.
- Preserve the existing stdout redaction behavior and clearly warn users that
access-tokenintentionally emits a bearer token that must not be logged or exposed.
- Create the configuration directory with owner-only permissions (
