T09 · Insecure Skill Coding Practices
- Location
scripts/setup_gmail.py:145- Finding
OAuth Client Secret Is Collected Through Echoed Terminal Input
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Gmail skill appears purpose-aligned, but it needs review because it handles private email and OAuth secrets with weak disclosure and unsafe credential-entry guidance.
Install only if you are comfortable granting read-only Gmail access and storing a refresh token locally. Do not paste OAuth client secrets into chat; enter them directly in a local, trusted terminal, and prefer a private SKILL_DATA_DIR or OS credential store. Revoke the Google OAuth grant if you stop using the skill.
scripts/setup_gmail.py:145OAuth Client Secret Is Collected Through Echoed Terminal Input
scripts/setup_gmail.py:48OAuth Credential File Is Permission-Hardened Only After Sensitive Data Is Written
SKILL.md:31Third-Party Runtime Dependencies Are Installed Without Version or Integrity Pinning
The documented behavior says the skill checks unread Gmail and produces a filtered digest, but the analyzed behavior indicates it primarily performs OAuth credential collection and token storage while not actually implementing the claimed inbox-reading workflow. This mismatch is dangerous because users and orchestrators may authorize sensitive Gmail access under false expectations, enabling credential harvesting or unnecessary persistence of highly sensitive tokens.
The skill declares no explicit tool or permission boundaries despite requiring environment access, file writes, network access, and shell execution. In an agent ecosystem, this increases the chance the skill is invoked with broader capabilities than users expect, especially because it handles OAuth credentials and local token storage.
The invocation phrases are broad enough to match common email-related requests, which can cause the skill to activate unexpectedly in situations where the user did not intend to authorize Gmail access or expose message summaries. Because the skill touches sensitive communications data, overbroad triggering materially raises privacy and consent risks.
The skill does not clearly warn that it accesses Gmail metadata and may surface sensitive email content in its output. Without an explicit privacy warning, users may unknowingly expose personal, financial, or security-related information through the agent interface or logs.
The skill description lacks clear non-activation conditions and boundary rules, making it ambiguous when the agent should or should not invoke this Gmail-accessing capability. In a privacy-sensitive context, ambiguous routing can lead to accidental mailbox access or disclosure of email content in response to general conversation prompts.
The guide explicitly tells the agent to ask the user for their OAuth Client ID and Client Secret, which encourages collection of sensitive credentials in the chat/session layer rather than directing the user to enter them locally. In an agent setting, this increases the chance that secrets are logged, retained, exposed to operators, or mishandled by downstream tooling, especially because there is no warning about sensitivity or safer handling path.
This code makes network calls to Gmail to retrieve unread message metadata, including sender, subject, and date, and later prints that information to stdout. While the module docstring describes functionality and required credentials, it does not explicitly warn that private inbox data will be fetched from a remote service and displayed, which meets the missing-warning criteria for code files handling potentially sensitive user data.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
def save_credentials(creds_data):
os.makedirs(DATA_DIR, exist_ok=True)
with open(CREDS_PATH, "w") as f:
json.dump(creds_data, f, indent=2)
os.chmod(CREDS_PATH, 0o600)
print(f"\nCredentials saved to {CREDS_PATH}")
No suspicious patterns detected.