T09 · Insecure Skill Coding Practices
- Location
scripts/teams_scan.py:85- Finding
Microsoft Graph Authentication Tokens Stored in an Unprotected Plaintext Cache
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims at a high level, but it handles Microsoft 365 messages and Teams auth tokens in ways that need careful review before use.
Install only if you are comfortable letting this skill read recent Outlook and optional Teams messages, store local scan results and token material, and send message excerpts to Telegram. Use the narrowest Graph scopes possible, keep state/config files out of source control and backups, secure or relocate the token cache, and require review before any reminder containing workplace content is sent externally.
scripts/teams_scan.py:85Microsoft Graph Authentication Tokens Stored in an Unprotected Plaintext Cache
scripts/teams_scan.py:259Excessive Plaintext Collection and Cross-Channel Disclosure of Teams Message Content
The declared description presents a multi-function skill centered on monitoring Outlook/Teams activity, sending reminders until dismissed, drafting personable replies, and surfacing action items. The supplied code chunk implements only a narrow subset related to reply drafting support: it retrieves one recent Outlook message by subject, writes thread fields to a JSON file, and can create an unsent Outlook reply draft. It does not monitor for new mail, remind via Telegram or Teams, inspect Teams messages, use Microsoft Graph, or extract action items. While the draft-reply portion is consistent with part of the description, the overall declared purpose materially overstates what this code chunk actually does.
The code is clearly related to one subset of the declared purpose: scanning Outlook Desktop email for recent potentially actionable messages. However, it does not implement several core declared capabilities, including nagging/reminders on Telegram or Teams, drafting email replies, or optional Teams monitoring via Graph. It also does not really 'surface action items' in a richer sense; it flags emails based on unread state and keyword heuristics and prints a JSON report. This is a material scope reduction compared with the declared description, so the description does not accurately represent what this code chunk actually does.
The skill explicitly instructs extraction of an Outlook message thread and key metadata in order to generate drafts, which can expose large amounts of sensitive email context to the agent and potentially to downstream channels or logs. In this skill's context, email threads may contain confidential business data, personal data, or secrets, so broad thread extraction materially increases privacy and data-loss risk beyond the minimum needed to draft a reply.
- Either a message `EntryID` (preferred) or search by subject + recent window.
Behavior:
- Extract the thread (best-effort) + key metadata.
- Generate 2 drafts:
- **Short** (2–5 sentences)
- **Normal** (5–10 sentences)
The skill describes operations that imply filesystem access, local state mutation, shell execution, and network communication, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an authorization ambiguity where an agent may invoke broader capabilities than a user expects, especially in a skill that accesses Outlook content, local config/state files, and external services like Telegram or Microsoft Graph.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# can print a lot to stderr, which can deadlock if piped.
err_path = out_path + ".stderr.txt"
with open(out_path, "w", encoding="utf-8") as out_f, open(err_path, "w", encoding="utf-8") as err_f:
p = subprocess.run(cmd, cwd=cwd, stdout=out_f, stderr=err_f, text=True, timeout=timeout_s)
if p.returncode != 0:
stderr = ""
This markdown file contains a natural-language style requirement to use 'Simple English words.' Because SQP-3 applies to all file types and flags language policy issues, this can be interpreted as enforcing an English-language constraint without documenting user opt-in or a justified locale-specific reason.
No suspicious patterns detected.