Back to skill

Security audit

email-pro-optimized

Security checks for vulnerabilities and agentic risk

Overview

This email skill has real email functionality, but it also ships insecure OAuth handling and unrelated repository/workspace automation that users should review before installing.

Install only if you are comfortable reviewing and controlling the scripts yourself. Use your own OAuth application credentials, revoke the exposed Azure secret if it belongs to you, avoid the bundled auto-push and sync maintenance scripts, and treat ~/.openclaw/credentials as sensitive because it can contain mailbox credentials and refresh tokens.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/authorize-outlook.sh:5
Finding
Hard-Coded Azure OAuth Client Secret<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize-outlook.sh:5-10` **Additional Locations**: `README.md:124-130`, `README.md:372-378` **Vulnerability Type**: Hard-coded OAuth application credential **Risk Level**: High ### Vulnerable Code ```bash python3 authorize.py outlook \ --client-id "0360031a-ad0e-4bce-9d2f-0c53eda894b8" \ --client-secret "914fb58f-4aea-4ddb-bb97-51d66581cfee" \ --tenant-id "40a99b83-a343-41ca-b303-3e122965a6d8" \ --name "outlook_live" ``` The same client ID, client secret, and tenant ID are reproduced in the README configuration examples. ### Technical Analysis A live-looking Azure OAuth client secret is embedded directly in an executable shell script and published in project documentation. A client secret is an authentication credential for the registered OAuth application and must not be distributed with client-side software. The shell launcher additionally passes the secret as a command-line argument. On systems where process arguments are visible to other users or monitoring software, the secret may be exposed through process listings, audit logs, shell tracing, or process inspection interfaces. Removing the value from the current files is insufficient if the project has already been distributed or committed to version control, because copies may remain in package archives and repository history. ### Attack Path 1. An attacker downloads the Skill package or reads its repository. 2. The attacker extracts the Azure client ID, tenant ID, and client secret from the shell script or README. 3. The attacker submits the exposed application credentials to compatible Microsoft OAuth endpoints. 4. Depending on the Azure application registration, configured permissions, redirect URIs, and tenant policy, the attacker may impersonate or abuse the registered OAuth client. 5. The attacker may also combine the credential with stolen authorization codes or refresh tokens associated with the application. ### Im ...[truncated 507 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke the exposed Azure client secret immediately and create a replacement only if a confidential client is genuinely required. 2. Remove the secret from the shell script, README, package releases, examples, and version-control history. 3. Load confidential values from protected environment variables, a secret manager, or a configuration file with restrictive permissions. 4. Do not pass secrets through command-line arguments. Read them through protected process input or a secret-management API. 5. Prefer an OAuth public-client flow with Authorization Code and PKCE for locally installed command-line applications, avoiding a distributable client secret. 6. Add automated secret scanning to development and release workflows. 7. Review Azure sign-in and application audit logs for use of the exposed credential. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/oauth_handler.py:20
Finding
OAuth Login CSRF and Account Confusion Due to Missing State Validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/oauth_handler.py:20-30` **Related Locations**: `scripts/oauth_handler.py:50-60`, `scripts/oauth_handler.py:98-108`, `scripts/oauth_handler.py:137-169`, `scripts/oauth_handler.py:174-206` **Vulnerability Type**: Missing OAuth request correlation and stale callback state **Risk Level**: High ### Vulnerable Code ```python class OAuthCallbackHandler(BaseHTTPRequestHandler): auth_code = None def do_GET(self): query = urlparse(self.path).query params = parse_qs(query) if 'code' in params: OAuthCallbackHandler.auth_code = params['code'][0] self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write( b'<html><body><h1>Authorization Success!</h1>' b'<p>You can close this window now.</p></body></html>' ) else: self.send_response(400) self.end_headers() ``` The authorization URL is generated without a `state` value: ```python params = { 'client_id': self.client_id, 'redirect_uri': self.redirect_uri, 'response_type': 'code', 'scope': 'https://www.googleapis.com/auth/gmail.modify', 'access_type': 'offline', 'prompt': 'consent' } return f"{self.auth_uri}?{urlencode(params)}" ``` The Outlook authorization flow has the same omission. ### Technical Analysis OAuth authorization requests must contain an unpredictable, single-use `state` value that is bound to the initiating session. The callback must reject responses whose state does not match. This implementation accepts the first request to the local callback containing any `code` parameter without verifying that the callback belongs to the authorization attempt initiated by the user. The authorization code is also held in the class variable `OAuthCallbackHandler.auth_code` and is not reset before starting ...[truncated 1693 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random `state` value for every authorization attempt using a source such as `secrets.token_urlsafe()`. 2. Include the state in the authorization URL and retain it only for the lifetime of that authorization attempt. 3. Require the callback to contain an exactly matching state and compare it using a constant-time comparison. 4. Reset all callback data before starting the HTTP server and reject duplicate or late callbacks. 5. Use Authorization Code with PKCE and validate the PKCE verifier during token exchange. 6. Bind explicitly to a loopback address and use an ephemeral available port rather than a fixed port where provider configuration permits it. 7. Explicitly stop and close the callback server after success or timeout. 8. Confirm the returned token response contains the expected provider, scopes, and account identity before saving it. 9. Do not save token responses that contain OAuth errors or lack a valid access token. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auto-push.py:14
Finding
Shell Command Injection Through Git Branch Name<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto-push.py:14-23` **Related Location**: `scripts/auto-push.py:124-140` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```python def run_command(cmd, cwd=None): try: result = subprocess.run( cmd, shell=True, cwd=cwd or SKILL_DIR, capture_output=True, text=True, timeout=30 ) return result.returncode == 0, result.stdout, result.stderr except Exception as e: return False, "", str(e) ``` A Git-derived value is interpolated into shell commands: ```python success, branch, _ = run_command("git rev-parse --abbrev-ref HEAD") if not success: print("Unable to determine the current branch") return False branch = branch.strip() success, stdout, stderr = run_command(f"git push origin {branch}") if not success: if "no upstream branch" in stderr.lower() or "set-upstream" in stderr.lower(): success, _, _ = run_command(f"git push -u origin {branch}") ``` ### Technical Analysis `subprocess.run(..., shell=True)` causes the command string to be interpreted by the operating-system shell. The branch value is obtained from repository metadata and concatenated into the command without shell-safe quoting or validation. Git reference names can contain multiple characters that have special significance to a shell. If an attacker can control the current branch name or manipulate the repository state, shell metacharacters or command-substitution syntax in that value may be evaluated by the shell rather than passed literally to Git. Escaping the commit message elsewhere in the script is incomplete and does not protect the branch interpolation. ### Attack Path 1. An attacker gains the ability to prepare or influence the Git repository used by the script. 2. The attacker creates or selects a branch name containing shell-significant syntax accepte ...[truncated 866 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `shell=True` from every subprocess invocation. 2. Pass commands as argument arrays: ```python subprocess.run( ["git", "push", "origin", branch], shell=False, cwd=cwd or SKILL_DIR, capture_output=True, text=True, timeout=30, check=False, ) ``` 3. Validate branch names with `git check-ref-format --branch` before using them. 4. Reject unexpected control characters and shell metacharacters as an additional defense. 5. Use `--` separators where supported to prevent values from being interpreted as options. 6. Apply the same array-based execution pattern to commit, log, status, add, and upstream-push operations. 7. Add security tests using adversarial branch names and repository metadata. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/auto-push.py:46
Finding
Undeclared Bulk Staging and Remote Publication of Repository Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto-push.py:46-57` **Related Location**: `scripts/auto-push.py:124-140` **Vulnerability Type**: Excessive repository access and unintended data publication **Risk Level**: High ### Vulnerable Code ```python def stage_changes(): print("\nStaging changes...\n") success, stdout, stderr = run_command("git add -A") if success: print("All changes have been staged") return True else: print(f"Staging failed: {stderr}") return False ``` The script subsequently publishes the resulting commit: ```python branch = branch.strip() success, stdout, stderr = run_command(f"git push origin {branch}") if success: print(f"Push completed for origin/{branch}") return True else: if "no upstream branch" in stderr.lower() or "set-upstream" in stderr.lower(): success, _, _ = run_command(f"git push -u origin {branch}") if success: print(f"Push completed for origin/{branch}") return True ``` ### Technical Analysis The Skill is declared as an email-management utility. Bulk staging and publication of every repository change is not necessary for reading, analyzing, or sending email. `git add -A` includes all tracked changes, deletions, and untracked files under the repository. The script then commits and pushes those changes to the existing `origin` remote without requiring the user to review the staged diff or approve each file. Although the script must be invoked separately, its behavior crosses the Skill's normal trust boundary and can publish unrelated source files or secrets accidentally placed in the repository. ### Attack Path 1. A credential, generated report, private configuration, or unrelated file is created inside the repository. 2. The user invokes `scripts/auto-push.py`, potentially believing it only publishes intended Skill updates. 3. `git add -A` stages the sensitive or unrelated file along with all ...[truncated 841 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the Git publication helper from the distributed email Skill unless it is an explicitly documented administrative feature. 2. Replace `git add -A` with an allowlist of specific project files selected by the user. 3. Display the exact remote URL, current branch, staged file list, and complete staged diff before committing. 4. Require explicit interactive confirmation before both commit and push operations. 5. Refuse to stage credential directories, token files, environment files, private keys, mailbox exports, and other sensitive patterns. 6. Add a secret-scanning step before commit and push. 7. Avoid automatically creating an upstream relationship. 8. Document that pushed data is retained in Git history and provide a safe recovery procedure for accidental disclosure. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/sync-updates.py:14
Finding
Undeclared Modification of a Separate Agent Workspace<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-updates.py:14-17` **Related Location**: `scripts/sync-updates.py:74-94` **Vulnerability Type**: Cross-workspace file modification beyond declared functionality **Risk Level**: Medium ### Vulnerable Code ```python SKILL_DIR = Path.home() / '.openclaw' / 'skills' / 'email-pro-optimized' WORKSPACE_DIR = Path.home() / '.openclaw' / 'workspace-telegram-bot1' SYNC_STATE_FILE = SKILL_DIR / '.sync-state.json' ``` ```python def sync_to_workspace(changed_files): if not changed_files: print("\nNo synchronization required") return True workspace_skill_dir = WORKSPACE_DIR / 'skills' / 'email-pro-optimized' workspace_skill_dir.mkdir(parents=True, exist_ok=True) for file_rel_path in changed_files: src = SKILL_DIR / file_rel_path dst = workspace_skill_dir / file_rel_path dst.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dst) return True ``` ### Technical Analysis The update utility contains a hard-coded path to a separate Telegram-bot workspace and copies Skill code and instructions into it. An email-management Skill does not require write access to another Agent workspace. The destination is not supplied by the user and there is no confirmation, ownership check, destination trust validation, backup, or protection against overwriting existing files. Copying `SKILL.md` and executable Python modules into another Agent workspace may change the behavior of that workspace when it next loads the Skill. The current artifact also contains syntax and name errors elsewhere in `sync-updates.py`, so the script cannot successfully complete in its reviewed form. The cross-workspace write remains an unsafe designed behavior that would become reachable if those errors were corrected. ### Attack Path 1. The update script is repaired or executed from a version where its existing syntax errors have been corrected. 2. A monitored sourc ...[truncated 870 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the hard-coded Telegram-bot workspace path. 2. Keep update operations confined to the installed Skill directory by default. 3. If synchronization is required, accept the destination through an explicit command-line option and require informed confirmation. 4. Resolve both source and destination paths and verify that they remain within approved directory boundaries. 5. Refuse to overwrite existing files unless the user explicitly authorizes each replacement. 6. Present a manifest and diff before copying executable code or Agent instructions. 7. Use atomic writes and create backups so partial synchronization cannot corrupt the destination. 8. Repair the existing syntax and name errors only after the cross-workspace security model has been redesigned and tested. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/analyze.py:46
Finding
Email Analyzer Retrieves Full Messages Despite Using Only Headers<![CDATA[ ## Vulnerability Details **File Location**: `scripts/analyze.py:46-58` **Vulnerability Type**: Excessive mailbox data retrieval **Risk Level**: Medium ### Vulnerable Code ```python status, messages = imap.search(None, 'ALL') msg_ids = messages[0].split()[-limit:] print(f"Found {len(msg_ids)} messages") print("Analyzing messages") categories = defaultdict(list) from_stats = defaultdict(int) start = time.time() if msg_ids: status, msg_data_list = imap.fetch(b','.join(msg_ids), '(RFC822)') else: msg_data_list = [] ``` The subsequent analysis only extracts metadata: ```python msg = BytesParser().parsebytes(msg_data_list[i][1]) from_addr = msg.get('From', 'Unknown') subject = msg.get('Subject', '(no subject)') date = msg.get('Date', '') ``` ### Technical Analysis The IMAP `(RFC822)` fetch item retrieves complete messages. This can include message bodies and attachments. However, the classifier only uses the `From`, `Subject`, and `Date` headers. The default analysis limit is 1,000 messages. As a result, a large amount of sensitive mailbox content is transferred from the provider and loaded into process memory without being required for classification. This violates data-minimization and least-privilege principles. No code path was found that exfiltrates this content to an unrelated third party. The issue is unnecessary collection and local exposure rather than confirmed external data theft. ### Attack Path 1. A user runs `scripts/analyze.py` with the default or a larger limit. 2. The script authenticates to the selected IMAP account. 3. It searches the entire inbox and selects up to the requested number of messages. 4. It requests each selected message in complete RFC822 form. 5. Full bodies and attachments are transferred and parsed even though only three headers are used. 6. Sensitive content is unnecessarily exposed to process memory, debugging tools, crash capture, or other local instrumentation. ### Impact Assessment The operat ...[truncated 438 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Request only the headers required for classification: ```python fetch_item = '(BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])' status, msg_data_list = imap.fetch(b','.join(msg_ids), fetch_item) ``` 2. Avoid requesting attachment metadata or message bodies unless a separate feature explicitly requires them. 3. Reduce the default message limit and require explicit user confirmation for large mailbox scans. 4. Validate IMAP response status before processing returned data. 5. Process messages incrementally rather than retaining a large batch of complete messages in memory. 6. Document exactly which mailbox metadata is collected and how long it remains in memory or output. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (50)

Credential Access

High
Category
Privilege Escalation
Content
**OAuth Token**: `~/.openclaw/credentials/oauth_tokens.json`

Automatically saved after authorization, contains access token and refresh token.

#### Gmail Mailbox (Optional)
Confidence
97% confidence
Finding
The README explicitly documents local storage of OAuth access and refresh tokens in a file under the user's home directory. If those tokens are stored unencrypted or exposed through weak file permissions, backups, logs, sync tools, or local compromise, an attacker could access mailbox contents and potentially send email as the user without knowing the account password.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description presents a general-purpose, high-performance email toolkit with IMAP read, SMTP write, OAuth 2.0, and concurrency across major providers. The supplied code instead performs a narrow task: it reads messages from an inbox over IMAP using locally stored credentials, parses subjects/senders, classifies emails, and outputs summary statistics. There is no SMTP functionality, no OAuth flow, no concurrent processing, and no clear implementation of provider-specific support for QQ/Gmail/Outlook. The primary purpose is materially different as well: this is an email analysis script, not a full email client/toolkit. Therefore the declared description does not accurately represent the observed behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a full-featured email tool covering QQ, Gmail, and Outlook, with IMAP/SMTP functionality, OAuth 2.0, concurrency, and performance claims. The supplied code chunk only defines a CLI wrapper for OAuth authorization, exposing subcommands for Gmail and Outlook and forwarding credentials to authorization handlers. This is only a narrow subset of the declared functionality (OAuth 2.0 for two providers) and lacks the primary advertised behaviors of reading/sending email, QQ support, and concurrent processing. Therefore, the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description is about email functionality (IMAP/SMTP/OAuth/concurrency/performance), but the actual code chunk contains no email-related logic at all. Instead, it performs source-control automation for a local skill directory: running git commands, enumerating changed files, committing them, and pushing to a remote repository. This is a materially different primary purpose and introduces undeclared capabilities involving local file/repository management and remote code publication. Therefore this is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
84% confidence
Finding
The core purpose mostly aligns at a high level: this is an email utility that can read/search/fetch and send mail for configured accounts. However, the declared description makes specific claims about OAuth 2.0 support, concurrent processing, and high-performance behavior, including a 4-5x speed improvement. None of those capabilities are evidenced in this code chunk. Instead, the code mainly provides a command-line wrapper around provider methods and accesses a local credentials file to manage accounts, including listing account metadata, which is not mentioned in the description. Because the declared purpose emphasizes capabilities not substantiated by the code and omits the local account/config management behavior, this is a meaningful description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description says this skill is an end-user email tool with IMAP/SMTP/OAuth/concurrent email handling across providers. However, the provided code chunk is not implementing those mail capabilities; it is a maintenance script for the skill package. Its primary purpose is operational upkeep: checking dependencies, verifying required files, reading local credential/token files, validating that another script contains expected symbols, and updating .skill-metadata.json with a bumped version and feature metadata. Those behaviors are materially different from the declared primary purpose. While some references align with the email domain (OAuth, providers, feature names), this chunk itself performs maintenance/admin tasks and local credential inspection, which are undeclared in the description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description presents a full email tool covering QQ/Gmail/Outlook, IMAP/SMTP operations, OAuth 2.0, and concurrent high-performance processing. The supplied code chunk is much narrower: it handles OAuth flows for Gmail and Outlook only, starts a local HTTP server on localhost:8080 to receive authorization callbacks, opens a browser for user consent, stores OAuth tokens under ~/.openclaw/credentials/oauth_tokens.json, and refreshes Gmail access tokens automatically. This is related to the OAuth portion of the description, but materially incomplete versus the declared primary purpose. Key advertised capabilities—QQ support, IMAP reading, SMTP sending, concurrency, and performance characteristics—are absent from the code shown. Therefore the description does not accurately represent what this specific code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
描述与代码部分一致:确实支持 QQ、Gmail、Outlook,也实现了邮件读取、发送和 OAuth 2.0(Gmail/Outlook)。但存在明显不匹配之处。首先,声明中的“并发处理”在代码中没有任何线程、异步、任务池或批量并发实现。其次,“高性能”“比 imap-smtp-email 快 4-5 倍”没有任何可见优化、基准测试或特殊实现支撑。再次,描述概括为 IMAP 读、SMTP 写,实际只有 QQ 使用 IMAP/SMTP;Gmail 与 Outlook 改为调用 Gmail API 和 Microsoft Graph API,这与声明的协议层能力不完全一致。最后,代码还会访问用户主目录下的 OAuth token 文件以加载凭证,这虽是支持 OAuth 的实现细节,但属于未在描述中明确提及的资源访问。综合看,技能主用途基本相关,但描述对能力和实现方式有实质性夸大/偏差,因此应判定为 mismatch。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents an end-user email capability: reading mail via IMAP, sending via SMTP, OAuth 2.0 support, provider compatibility, and performance claims. The supplied code does not implement email handling at all. Instead, it is a developer utility script for syncing skill source files, maintaining changelogs, updating version metadata, and preparing/prompting for ClawHub publication. This is a materially different primary purpose and introduces undeclared filesystem and release-management behavior unrelated to the stated email tool functionality.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill contains shell-based Git automation that is not justified by an email tool's stated function. Because it combines shell execution with source-control operations, it can be repurposed to run arbitrary commands or publish repository contents, making the mismatch in context especially risky.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def run_command(cmd, cwd=None):
    """运行命令"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            cwd=cwd or SKILL_DIR,
Confidence
98% confidence
Finding
Using shell=True for tool execution creates a parameter-abuse pathway because command strings are assembled and executed by the shell instead of being passed as structured arguments. In this script, dynamic values like branch names and commit content can become part of shell-parsed input, enabling arbitrary command execution if manipulated.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This markdown file describes actions that can transmit data externally by sending emails, including HTML content and attachments, but it does not include any user warning about verifying recipients, attachment contents, or the privacy implications of outbound mail. The same document also promotes email backup/export and automated checking of mailbox contents, which affect sensitive user data, yet no cautionary disclosure is provided.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The security section states QQ uses an authorization code instead of a password and implies safer credential handling, but the same README shows `auth_code`, `client_secret`, and OAuth tokens being stored in plaintext under `~/.openclaw/credentials/`. This is an intent/documentation contradiction because the security claims suggest stronger handling than the documented storage practice actually provides.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and instructs use of capabilities that inherently require shell, network access, and reading/writing credential files, yet it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens containment and user awareness, increasing the chance the skill operates with broader agent privileges than necessary when handling sensitive email accounts and OAuth tokens.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The skill metadata and user-facing documentation are presented in Chinese throughout, with no indication that users may choose another language or that the tool is intentionally limited to a Chinese-speaking or region-specific context. Under the locale policy, forcing a specific language without opt-in can be a natural-language policy violation.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill provides a straightforward email sending command but does not warn users that execution can trigger real outbound messages to external recipients. In an agent setting, that omission raises the risk of accidental data leakage, unauthorized contact, spam-like behavior, or reputational harm if commands are run with the wrong recipient or content.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill explicitly stores account credentials and OAuth tokens in local files but does not prominently warn users about the sensitivity, persistence, or protection requirements of those secrets. In an email-management context, compromised local token or credential files can grant ongoing access to mailbox contents and sending capability across multiple providers.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script loads stored email credentials from a local secrets file, logs into the mailbox, and reads message contents from the inbox without any explicit user consent prompt, warning, or access-scope confirmation at runtime. In an agent skill context, this is sensitive-data access because it touches both authentication secrets and private mailbox content, increasing the risk of unintended surveillance, overcollection, or misuse if invoked unexpectedly.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The script hard-codes an OAuth client ID, client secret, and tenant ID directly in a shell script and immediately invokes the authorization flow. Even if these values are intended for a public integration, embedding a client secret in distributed skill code exposes it to any user or attacker who can read the file, enabling unauthorized reuse of the application credentials and making secret rotation difficult.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This code requires OAuth client secrets as command-line arguments for both Gmail and Outlook, which is a sensitive credential-handling operation. The file provides no warning in comments, help text, or runtime output about the security implications of supplying secrets on the command line, where they may be exposed via shell history or process listings.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
This file adds repository automation that stages, commits, and pushes local changes, which is unrelated to the advertised email-processing purpose of the skill. In a skill package, unrelated source-control automation expands the attack surface and can be used to exfiltrate local code or silently publish unintended changes.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_command(cmd, cwd=None):
    """运行命令"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            cwd=cwd or SKILL_DIR,
Confidence
96% confidence
Finding
The script executes shell commands through subprocess.run with shell=True, which is dangerous because later calls interpolate variable data such as the current Git branch into command strings. If a branch name or other command component contains shell metacharacters, it can trigger command injection and execute arbitrary commands on the host.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The main flow automatically stages all changes, commits them, and pushes to the remote repository without any interactive confirmation step. This can cause irreversible publication of sensitive files, secrets, or unintended modifications, especially if the script is run accidentally or integrated into automated workflows.

Natural-Language Policy Violations

Medium
Confidence
85% confidence
Finding
The module title, support text, docstrings, CLI description, help strings, and user-facing messages are written in Chinese, and the file does not indicate any user opt-in or alternative locale. Under the policy, forcing a specific language without user choice can be a natural-language policy violation unless the constraint is explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The script's natural-language docstrings and user-facing output are exclusively in Chinese, which effectively fixes the interaction language without offering user opt-in or an explanation that the tool is region-specific. The policy scope includes natural-language content in code files, so this qualifies as a locale/language policy concern.

Static analysis

No suspicious patterns detected.