T09 · Insecure Skill Coding Practices
- Location
scripts/auth.py:43- Finding
Shared OAuth Tokens Stored in Plaintext Without Explicit Restrictive Permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/auth.py, lines 19 and 43–58
Vulnerability Type: Plaintext credential storage with insufficient access-control enforcement
Risk Level: MediumVulnerable Code
python # Global token cache path shared by all 1688 Skills TOKEN_CACHE_PATH = Path.home() / ".openclaw" / "workspace" / "skills" / ".1688_token_cache.json"python def save_token_to_cache(token_data, app_key): """Save token to cache""" ensure_cache_dir() # Calculate expiration time expires_in = int(token_data.get('expires_in', 3600)) expires_at = time.time() + expires_in cache_data = { 'access_token': token_data['access_token'], 'refresh_token': token_data.get('refresh_token'), 'expires_at': expires_at, 'app_key': app_key } with open(TOKEN_CACHE_PATH, 'w') as f: json.dump(cache_data, f)Technical Analysis
The authentication module stores both the access token and refresh token in an unencrypted JSON file. It does not explicitly assign restrictive permissions to the cache directory or file, verify ownership before reading, or reject unsafe file types such as symbolic links.
Consequently, credential confidentiality depends on the process umask and preexisting permissions of the surrounding workspace. The documented cross-Skill cache design also gives other 1688 Skills access to credentials that this Skill could otherwise keep private, increasing the trust boundary beyond the minimum privilege required for ranking and category queries.
Attack Path
- The user runs a ranking or category query with
ALI1688_REFRESH_TOKENconfigured. get_access_token()sends the refresh request to the official 1688 endpoint and receives OAuth tokens.save_token_to_cache()writes the access token and potentially the refresh token to.1688_token_cache.json.- A malicious local process, another Skill, or another local user with access to the workspace ...[truncated 886 chars]
- The user runs a ranking or category query with
- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential store or another dedicated secret-management facility instead of a plaintext workspace file.
- If a file cache is unavoidable, create its directory with mode
0700and the cache file with mode0600, without relying on the ambient umask. - Write tokens atomically through a securely created temporary file and then replace the destination.
- Before reading or replacing the cache, verify that it is a regular file, is not a symbolic link, is owned by the expected user, and has no group or other permissions.
- Avoid sharing a single token cache among unrelated Skills. Use per-Skill or explicitly scoped credential storage unless cross-Skill sharing is indispensable and approved.
- Do not retain the refresh token in the cache unless caching it is necessary. Minimize the token material and lifetime stored on disk.
- Provide token revocation and cache deletion procedures for suspected disclosure.
