T09 · Insecure Skill Coding Practices
- Location
scripts/rtm.py:166- Finding
Authentication Token Stored Without Enforced Restrictive Permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/rtm.py, lines 166–169
Vulnerability Type: Plaintext sensitive credential stored with umask-derived permissions
Risk Level: MediumVulnerable Code
python rsp = api_call("rtm.auth.getToken", shared_secret, api_key, frob=frob) token = rsp["auth"]["token"] username = rsp["auth"]["user"]["username"] TOKEN_PATH.write_text(token)Technical Analysis
The authentication token is written in plaintext to
~/.rtm_tokenusingPath.write_text(). This operation does not explicitly enforce owner-only permissions; the resulting mode depends on the process umask. In an environment with a permissive umask, other local users may be able to read the token.The token is especially sensitive because the authorization flow requests RTM's
deletepermission, its highest permission tier. AlthoughSKILL.mdwarns users to applychmod 600, documentation does not provide the same protection as enforcing secure permissions in code.Attack Path
- A user runs
scripts/rtm.py auth. - The Skill requests an RTM token carrying
deletepermission. - The token is saved to
~/.rtm_tokenwith permissions determined by the current umask. - If those permissions allow access by another local account, an attacker reads the token.
- The attacker uses the stolen token with the RTM API and associated API credentials to access or alter the linked account's data.
This path requires local read access to the token file and permissions that expose it.
Impact Assessment
Disclosure of the token can compromise the linked Remember The Milk account within the granted API scope. An attacker able to use it may read task and note data, create or modify tasks, complete tasks, and permanently delete tasks or notes. The issue does not directly grant operating-system privilege escalation, but it exposes a credential with broad application-level privileges.
- A user runs
- Remediation
View remediation
Remediation Suggestions
- Create the token file atomically with mode
0600, rather than relying on the process umask. - Open the destination with restrictive flags such as
O_CREAT | O_WRONLY | O_TRUNCand an explicit0o600mode. - Prevent symlink-following where the platform supports
O_NOFOLLOW, and verify that the destination is a regular file owned by the current user. - If replacement is required, write to a securely created file in the same directory, set mode
0600, flush it, and atomically rename it. - Explicitly apply
chmod(0o600)after creation as defense in depth. - On token loading, reject files that are not owned by the current user or are readable or writable by group or others.
- Consider using an operating-system credential store instead of a plaintext file when available.
- Continue documenting that the token grants full RTM access, but do not rely on users to secure it manually.
- Create the token file atomically with mode
