T09 · Insecure Skill Coding Practices
- Location
scripts/refresh_token.py:28- Finding
OAuth Access Token Exposed Through Standard Output and Insecure Plaintext Storage
- Content
View full analysis
Vulnerability Details
File Location:
scripts/refresh_token.py, lines 28–49
Vulnerability Type: Plaintext sensitive-data exposure
Risk Level: MediumVulnerable Code:
python # Update the secrets.env file env_path = os.path.expanduser('~/.config/google-calendar/secrets.env') # Read existing lines, replace or add GOOGLE_ACCESS_TOKEN lines = [] if os.path.exists(env_path): with open(env_path, 'r') as f: lines = f.readlines() new_lines = [] token_set = False for line in lines: if line.startswith('export GOOGLE_ACCESS_TOKEN='): new_lines.append(f'export GOOGLE_ACCESS_TOKEN={access_token}\n') token_set = True else: new_lines.append(line) if not token_set: new_lines.append(f'export GOOGLE_ACCESS_TOKEN={access_token}\n') with open(env_path, 'w') as f: f.writelines(new_lines) print(json.dumps(resp_data, indent=2))Technical Analysis
The OAuth access token returned by Google is written in plaintext to
~/.config/google-calendar/secrets.env. The script does not create the parent directory with restrictive permissions, explicitly set the file mode to0600, verify existing file ownership, or perform an atomic replacement.The entire OAuth response is also printed to standard output. Because the response contains
access_token, the credential may be captured by terminal history tooling, agent transcripts, automation logs, CI logs, process wrappers, or redirected output files.This behavior exceeds the minimum disclosure necessary for token refresh. Persisting an access token may be operationally useful, but printing it is unnecessary, and storage should use a protected secret-management mechanism.
The separate transmission of the client ID, client secret, and refresh token to
https://oauth2.googleapis.com/tokenis expected OAuth behavior and is necessary for refresh-token exchange. No transmission to an unknown or attacker- ...[truncated 1220 chars]- Remediation
View remediation
Remediation Suggestions
- Do not print the complete OAuth response. Emit only non-sensitive status information, such as successful refresh and token expiry.
- Store the token using the documented OpenClaw secret-management facility instead of a plaintext environment file.
- If file storage is unavoidable, create the configuration directory with mode
0700and the token file with mode0600. - Verify that an existing token file is a regular file owned by the current user and is not a symbolic link.
- Write to a securely created temporary file in the same directory, apply restrictive permissions, flush it, and atomically replace the destination.
- Avoid preserving access tokens longer than operationally necessary, and document revocation and rotation procedures.
- Ensure logs, exception handlers, and diagnostic output redact
access_token,refresh_token,client_secret, and authorization headers.
