T09 · Insecure Skill Coding Practices
- Location
scripts/_temu_token_store.py:10- Finding
Temu access tokens are stored in plaintext without enforced restrictive permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/_temu_token_store.py:10-35,scripts/_temu_token_store.py:62-68
Vulnerability Type: Plaintext credential storage with environment-dependent file permissions
Risk Level: HighEvidence
python DEFAULT_STORE_PATH = os.path.expanduser("~/.linkfox/temu-access-tokens.json") def store_path() -> str: return os.environ.get("TEMU_TOKEN_STORE_PATH", DEFAULT_STORE_PATH) def _load_store() -> dict: path = store_path() if not os.path.isfile(path): return {"stores": []} with open(path, encoding="utf-8") as f: data = json.load(f) if "stores" not in data or not isinstance(data["stores"], list): return {"stores": []} return data def _save_store(data: dict) -> None: path = store_path() parent = os.path.dirname(path) if parent: os.makedirs(parent, exist_ok=True) with open(path, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) f.write("\n")The sensitive value written to this file is constructed as follows:
python entry = { "site": site, "managementType": management_type, "tokenPurpose": token_purpose, "accessToken": access_token, "updatedAt": _utc_now(), }Technical Analysis
Temu access tokens are persisted as unencrypted JSON. The implementation does not explicitly create the containing directory with mode
0700or the credential file with mode0600. Consequently, effective permissions depend on the process umask and any permissions already present on the configured path.The
TEMU_TOKEN_STORE_PATHenvironment variable also permits an arbitrary storage path. This is useful for configuration, but no checks ensure that the destination is a regular owner-controlled file, that its parent directory is trustworthy, or that an existing destination is not a symbolic link.The iss ...[truncated 1526 chars]
- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential manager, such as Keychain, Credential Manager, or Secret Service, instead of a plaintext JSON file.
- If file storage remains necessary:
- Create the parent directory with mode
0700. - Create a new credential file atomically with mode
0600. - Verify and repair permissions on existing files before reading or writing them.
- Reject symbolic links and non-regular destination files.
- Write to a securely created temporary file in the same directory, call
fsync, and atomically replace the destination.
- Create the parent directory with mode
- Validate that the configured storage path is owner-controlled.
- Avoid storing tokens longer than required and provide token deletion and rotation commands.
- Document that plaintext credentials may be included in backups and synchronized home directories.
- Where supported, store only a credential-manager reference in the JSON metadata.
