T09 · Insecure Skill Coding Practices
Error
- Location
- knuspr_cli.py:160
- Finding
- Session Cookies Are Persisted Without Enforced Restrictive Permissions## Vulnerability Details **File Location**: `knuspr_cli.py`, lines 160–167 **Vulnerability Type**: Insecure storage of reusable authentication tokens **Risk Level**: High ```python def _save_session(self) -> None: """Save session cookies to file.""" session_data = { "cookies": self.cookies, "user_id": self.user_id, "address_id": self.address_id, } with open(SESSION_FILE, "w") as f: json.dump(session_data, f) ``` ### Technical Analysis The application serializes reusable authentication cookies, the user identifier, and the address identifier into `~/.knuspr_session.json`. The file is opened using the default process permissions, without securely creating it with mode `0600` or verifying its ownership and permissions. Consequently, the file's effective permissions depend on the user's current `umask` and any pre-existing file metadata. In an environment with a permissive `umask`, or where the destination file was created previously with weak permissions, another local user or process may be able to read the session cookies. The cookies are automatically attached to subsequent requests through the `Cookie` header. They therefore constitute reusable authentication material rather than harmless application configuration. ### Attack Path 1. A user authenticates to Knuspr through the CLI. 2. `_save_session()` writes the returned cookies to `~/.knuspr_session.json`. 3. The file receives permissions derived from the process `umask`, or retains insecure permissions from an existing file. 4. Another local user, compromised process, or application running under an account with read access obtains the cookie values. 5. The attacker replays the cookies in requests to Knuspr. 6. If the server-side session remains valid, the attacker operates within the victim's authenticated Knuspr session. Exploitation requires local read access to the session file or its contents; the ...[truncated 675 chars]
- Remediation
- ## Remediation Suggestions 1. Create the session file atomically with owner-only permissions: - Use `os.open()` with flags such as `O_WRONLY | O_CREAT | O_TRUNC` and mode `0o600`. - Wrap the resulting descriptor with `os.fdopen()`. 2. Write to a securely created temporary file in the same directory, flush and synchronize it, set mode `0600`, and atomically replace the destination. 3. Before reading an existing session file: - Verify that it is a regular file. - Verify that it is owned by the current user. - Reject symlinks where the platform supports safe no-follow behavior. - Reject or repair group-readable and world-readable permissions. 4. Store reusable session secrets in the operating system's credential manager or keyring where feasible. 5. Apply equivalent protections to any other file that may contain credentials or tokens. 6. Update the documentation so that “secure session storage” is claimed only after these controls are enforced. 7. On logout, continue deleting the local session file and invalidate the session server-side whenever possible.
