Back to skill

Security audit

Unified Mailbox Ai

Security checks for vulnerabilities and agentic risk

Overview

This email-monitoring skill is coherent in purpose, but it asks for and persists more mailbox, calendar, credential, agent, and cron authority than its task safely requires.

Review carefully before installing. Use only on accounts where automated AI summarization and Telegram forwarding are acceptable, reduce Microsoft Graph permissions to read-only, avoid the empty Gmail keyring password setup, do not accept cron or shell-profile changes unless you understand them, and inspect any existing crontab before running the installer.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (7)

T01 · Skill Instruction Hijacking

Error
Location
scripts/unified_mailbox_ai.py:307
Finding

Untrusted Email Content Is Passed to a Tool-Capable AI Agent

Content
View full analysis
--no-input' if GMAIL_ENABLED else '' ) # Prompt sent to the AI; output must be in English (the bot reply language) email_summary = json.dumps(new_emails, ensure_ascii=False, indent=2) message = f"""Process these {len(new_emails)} new unread email(s). Do everything silently — no step headers, no internal notes, no follow-up questions. Output ONLY the final notification block in English. DO SILENTLY (no output for these): {gmail_body_line} - For any is_meeting_invite=true, check the configured calendar(s): {calendar_block} - Mark every email: python3 {__file__} mark --id "" OUTPUT (exactly this format, nothing else, all in English): 📬 {len(new_emails)} new email(s) [One block per email:] [Outlook/Gmail] From: Subject: Summary: <1-2 sentence summary in English> [Only if is_meeting_invite=true] Event time: | ⚠️ Conflicts with "" / ✅ No conflict Emails: {email_summary}""" result = subprocess.run([ OPENCLAW_BIN, 'agent', '--message', message, '--deliver', '--to', TELEGRAM_USER ]) ``` ### Technical Analysis Sender-controlled email fields are serialized directly into the instruction context passed to an OpenClaw agent. These fields include senders, subjects, Outlook body previews, and potentially full Gmail bodies fetched by the agent. The prompt does not provide an enforceable trust boundary between system instructions and mailbox content. Text in an email can therefore masquerade as a new instruction. The invoked agent is also instructed to run mailbox, calendar, and local Python commands, while the Skill declares Bash, Read, and Write capabilities. Pr ...[truncated 1361 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/unified_mailbox_ai.py:10
Finding

Microsoft Graph Token Requests Unnecessary Write and Send Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/unified_mailbox_ai.py:79
Finding

Microsoft Graph Bearer Token Is Duplicated into General Agent Configuration

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:151
Finding

Installer Inputs Permit Persistent Shell and Cron Command Injection

Content
View full analysis
> "$HOME/.bashrc" success "Added to ~/.bashrc (run 'source ~/.bashrc' to reload)" fi echo # ── Step 7: Register skill in agent's skills list ─────────────────────── ask "Register unified-mailbox-ai in your main agent's skills list? [Y/n]" register if [[ ! "$register" =~ ^[Nn]$ ]]; then python3 - "$OPENCLAW_CONFIG" <<'PYEOF' import json, sys config_path = sys.argv[1] with open(config_path) as f: config = json.load(f) agents = config.get('agents', {}).get('list', []) for agent in agents: skills = agent.setdefault('skills', []) if 'unified-mailbox-ai' not in skills: skills.append('unified-mailbox-ai') with open(config_path, 'w') as f: json.dump(config, f, indent=2) print('Registered unified-mailbox-ai with all agents') PYEOF success "Skill registered" fi echo # ── Step 8: Set up cron ───────────────────────────────────────────────── ask "Set up a cron job to auto-check every 5 minutes? [Y/n]" setup_cron if [[ ! "$setup_cron" =~ ^[Nn]$ ]]; then GMAIL_ENV="" KEYRING_ENV="" if [ -n "$GMAIL_ACCOUNT" ]; then GMAIL_ENV="EMAIL_MONITOR_GMAIL_ACCOUNT=\"$GMAIL_ACCOUNT\"" KEYRING_ENV="GOG_KEYRING_PASSWORD=\"\"" fi CRON_LINE="*/5 * * * * PATH=\$HOME/.npm-global/bin:/ ...[truncated 2000 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:151
Finding

Gmail OAuth Keyring Is Configured with an Empty Password

Content
View full analysis
> "$HOME/.bashrc" success "Added to ~/.bashrc (run 'source ~/.bashrc' to reload)" fi ``` The same empty value is propagated to cron at `install.sh:190-195`: ```bash GMAIL_ENV="" KEYRING_ENV="" if [ -n "$GMAIL_ACCOUNT" ]; then GMAIL_ENV="EMAIL_MONITOR_GMAIL_ACCOUNT=\"$GMAIL_ACCOUNT\"" KEYRING_ENV="GOG_KEYRING_PASSWORD=\"\"" fi CRON_LINE="*/5 * * * * PATH=\$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin $KEYRING_ENV $GMAIL_ENV EMAIL_MONITOR_TELEGRAM_USER=\"$TELEGRAM_USER\" /usr/bin/python3 \$HOME/.openclaw/workspace/skills/unified-mailbox-ai/scripts/unified_mailbox_ai.py auto-notify" ``` ### Technical Analysis The installer and documentation deliberately set the `gog` file-keyring password to an empty string so that unattended cron runs can access Gmail and Google Calendar credentials. This removes meaningful password-based protection from the file credential store. Although filesystem permissions may still offer some protection, disclosure of the keyring file through another process, backup, archive, agent tool, or permissions mistake may expose usable OAuth material without an additional secret. ### Attack Path 1. The user follows the documented setup and authorizes Gmail and Calendar access through `gog`. 2. The file keyring is configured for non-interactive access with an empty password. 3. An attacker obtains read access to the credential files through local compromise, backup disclosure, or a ...[truncated 463 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
install.sh:195
Finding

Installer Deletes Unrelated Crontab Entries Using Broad Pattern Matching

Content
View full analysis
/dev/null | grep -v 'unified_mailbox_ai\|email_monitor'; echo "$CRON_LINE") | crontab - ``` ### Technical Analysis Before adding its own task, the installer removes every crontab line matching either `unified_mailbox_ai` or the generic string `email_monitor`. The filtering is not limited to an exact command or a unique marker owned by this project. Consequently, unrelated scheduled tasks whose commands, comments, paths, or arguments contain either string are silently removed. The cron task itself is a disclosed and functionality-related persistence mechanism. The vulnerability is the overbroad destructive replacement behavior, not the mere use of cron. ### Attack Path 1. The user already has an unrelated crontab entry containing `email_monitor` or `unified_mailbox_ai`. 2. The user accepts the installer's cron setup prompt. 3. `grep -v` removes the unrelated entry while rebuilding the crontab. 4. The modified crontab is installed without warning that another task was removed. 5. The unrelated scheduled operation no longer runs. ### Impact Assessment Potential impact includes loss of monitoring, backups, synchronization, maintenance, security checks, or other scheduled user processes. The scope is the current user's crontab. This does not directly grant additional privileges to an attacker, but it can cause availability and operational integrity failures. ]]>
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
install.sh:52
Finding

Installer Downloads and Executes an Unpinned Python Dependency

Content
View full analysis
/dev/null; then warn "Python package 'msal' is not installed (required for Outlook support)." ask "Install it now with pip? [y/N]" install_msal if [[ "$install_msal" =~ ^[Yy]$ ]]; then pip install --user msal || pip3 install --user msal success "msal installed" else warn "Skipping. You'll need to install msal manually if you use Outlook." fi else success "Python package 'msal' is installed" fi ``` ### Technical Analysis The installer requests the latest package named `msal` from whatever package index and pip configuration are active. It does not pin an audited version, verify hashes, constrain transitive dependencies, or ensure that pip corresponds to the same Python interpreter used by the Skill. Python package installation may execute package build hooks or install compromised code. A malicious configured index, dependency compromise, or future upstream compromise could therefore introduce code that runs under the installing user's account. The package name is not visibly typosquatted, and the audit found no evidence that the current `msal` package is malicious. The risk arises from unsafe, mutable dependency resolution. ### Attack Path 1. `msal` is absent, and the user accepts the install prompt. 2. `pip` resolves the package and transitive dependencies from its configured index. 3. The index, package release, or dependency is compromised, or local pip configuration redirects resolution to an attacker-controlled repository. 4. pip downloads and processes the malicious package. 5. Installation hooks or later imports execute attacker-controlled code as the installing user. ### Impact Assessment Successful supply-chain exploitation can provide arbitrary code execution with the ins ...[truncated 170 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (43)

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The documentation instructs users to set GOG_KEYRING_PASSWORD="", which weakens protection of locally stored Google credentials by encouraging an empty password for the file-backed keyring. In practice, this lowers the barrier for local compromise of mailbox and calendar access tokens, especially on shared systems or where home-directory files are exposed.

Content

Scanner excerpt · README.md (reported line 107)May include surrounding context.

bash
export EMAIL_MONITOR_TELEGRAM_USER="123456789"
export EMAIL_MONITOR_GMAIL_ACCOUNT="you@gmail.com"
export GOG_KEYRING_PASSWORD=""

C. crontab line (used by the auto-monitor; see step 4):

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The cron example embeds GOG_KEYRING_PASSWORD="" directly in the crontab, normalizing insecure secret handling and disabling effective protection for the file-based keyring. Cron entries and process environments can be exposed to local users, making credential theft easier if the host is compromised or multi-user.

Content

Scanner excerpt · README.md (reported line 126)May include surrounding context.

Add:

text
*/5 * * * * PATH=$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin GOG_KEYRING_PASSWORD="" EMAIL_MONITOR_GMAIL_ACCOUNT="you@gmail.com" EMAIL_MONITOR_TELEGRAM_USER="123456789" /usr/bin/python3 $HOME/.openclaw/workspace/skills/unified-mailbox-ai/scripts/unified_mailbox_ai.py auto-notify

Notes:

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The troubleshooting section reinforces use of a file-backed keyring with GOG_KEYRING_PASSWORD="", again encouraging insecure storage of OAuth credentials for Gmail and Calendar. Because this skill accesses highly sensitive communications data, weakening credential protection materially raises the risk of account compromise.

Content

Scanner excerpt · README.md (reported line 204)May include surrounding context.

Gmail returns "credentials store locked" or "No auth"

Your gog keyring is using GNOME keyring (default on Linux), which is locked when running outside a desktop session. Switch to file backend:

bash
gog auth keyring file
gog auth add <your-email> --services gmail,calendar

And ensure GOG_KEYRING_PASSWORD="" is set wherever you run the script.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · README.md (reported line 213)May include surrounding context.

md
script.

### Gmail Calendar returns 403
You need to enable the **Google Calendar API** in your Google Cloud project (it's separate from the Gmail API). Visit https://console.developers.google.com/apis/api/calendar-json.googleapis.com and click Enable.

### Cron runs but never pushes
Cron's PATH usually doesn't include `~/.npm-global/bin`, so `openclaw` can't be found. Either set `PATH=...` in the crontab line or symlink `openclaw` into `/usr/local/bin`.

---

## License

MIT

---

## Acknowledgements

Built on top of:
- [OpenClaw](https://openclaw.ai) — the agent framework
- [`outlook-graph`](https://clawhub.ai/byungkyu/outlook-graph) — Microsoft Graph integration
- [`gog`](https://gogcli.sh) — Google Workspace CLI

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The documented purpose is mailbox monitoring, but the referenced behavior includes persistent installation actions such as modifying shell/config files, registering the skill, and creating cron jobs. That mismatch is dangerous because it can cause the agent to perform privileged, long-lived system changes a user did not clearly authorize, which materially expands the trust boundary beyond reading email and reporting summaries.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

Google Calendar

bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · install.sh (reported line 158)May include surrounding context.

sh
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · install.sh (reported line 190)May include surrounding context.

sh
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · install.sh (reported line 193)May include surrounding context.

sh
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · install.sh (reported line 195)May include surrounding context.

sh
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · install.sh (reported line 208)May include surrounding context.

sh
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 147)May include surrounding context.

python
### Google Calendar
```bash
GOG_KEYRING_PASSWORD="" GOG_ACCOUNT="$EMAIL_MONITOR_GMAIL_ACCOUNT" gog calendar events primary --from <ISO_START> --to <ISO_END> --json --no-input
```

---

Lp1

High
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The script performs outbound network operations to Microsoft Graph and indirectly to other services via external tools, yet the detected network capability is not covered by declared permissions. This undermines least-privilege expectations and can lead to unauthorized data transfer from mailboxes and calendars.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The script performs outbound network operations to Microsoft Graph and indirectly to other services via external tools, yet the detected network capability is not covered by declared permissions. This undermines least-privilege expectations and can lead to unauthorized data transfer from mailboxes and calendars.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 87)May include surrounding context.

md
# ── Outlook ──────────────────────────────────────────────────────────────────

def get_access_token():
    """Load and auto-refresh the access token from ms_tokens.json."""
    with open(TOKEN_CACHE_FILE) as f:
        data = json.load(f)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 56)May include surrounding context.

python
# ── Outlook ──────────────────────────────────────────────────────────────────

def get_access_token():
    """Load and auto-refresh the access token from ms_tokens.json."""
    with open(TOKEN_CACHE_FILE) as f:
        data = json.load(f)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 144)May include surrounding context.

python
def fetch_gmail_unread():
    """Fetch unread Gmail emails via the gog CLI."""
    try:
        env = os.environ.copy()
        env['GOG_ACCOUNT'] = GMAIL_ACCOUNT
        # file keyring backend needs this env var in non-interactive contexts (cron); empty means no password
        env.setdefault('GOG_KEYRING_PASSWORD', '')

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 146)May include surrounding context.

python
try:
        env = os.environ.copy()
        env['GOG_ACCOUNT'] = GMAIL_ACCOUNT
        # file keyring backend needs this env var in non-interactive contexts (cron); empty means no password
        env.setdefault('GOG_KEYRING_PASSWORD', '')
        result = subprocess.run(
            ['gog', 'gmail', 'search', 'is:unread', '--max', '20',

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The prompt includes concrete authenticated command lines for accessing Google Calendar, including account context and auth-related environment variables, and hands them to an external agent. This is dangerous not because the string alone steals credentials, but because it encourages an agent to operate with the user's authenticated context against additional sensitive data sources.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 303)May include surrounding context.

python
if OUTLOOK_ENABLED:
        calendar_lines.append(f'    Outlook: python3 {OUTLOOK_SCRIPT} calendar-list --days 7 --top 20')
    if GMAIL_ENABLED:
        calendar_lines.append(f'    Google:  GOG_KEYRING_PASSWORD="" GOG_ACCOUNT={GMAIL_ACCOUNT} gog calendar events primary --from $(date -u +%Y-%m-%dT%H:%M:%SZ) --to $(date -u -d \'+7 days\' +%Y-%m-%dT%H:%M:%SZ) --json --no-input')
    calendar_block = '\n'.join(calendar_lines) if calendar_lines else '    (no calendars configured)'

    gmail_body_line = (

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The prompt instructs the external agent to fetch full Gmail message bodies using the user's authenticated account context. In this mailbox-monitoring setting, expanding from previews to full message retrieval materially increases exposure of sensitive content to an external AI-controlled workflow.

Content

Scanner excerpt · scripts/unified_mailbox_ai.py (reported line 307)May include surrounding context.

python
calendar_block = '\n'.join(calendar_lines) if calendar_lines else '    (no calendars configured)'

    gmail_body_line = (
        f'- For Gmail emails, fetch full body: GOG_KEYRING_PASSWORD="" GOG_ACCOUNT={GMAIL_ACCOUNT} gog gmail view <thread_id> --no-input'
        if GMAIL_ENABLED else ''
    )

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Untrusted email contents are embedded into a prompt sent to an external AI process that is also instructed to fetch more data and deliver summaries outward. In a mailbox skill, this is especially dangerous because an attacker can send crafted email content that causes sensitive mailbox data to be exposed or influences the agent to take privacy-impacting actions.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The prompt treats email content as part of the task context without robust delimitation, quoting, or explicit instructions to ignore directives inside emails. Since inbound email is attacker-controlled, malicious content can semantically override or redirect the agent's behavior, making prompt injection a realistic exploitation path.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code hands untrusted email-derived content to a general-purpose external AI agent along with instructions to inspect calendars, fetch more content, mark state, and deliver messages. In the context of an email-monitoring skill, this is particularly dangerous because email is attacker-controlled input and can be used to steer an agent with broader execution capabilities than the user likely intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly states that unread email content is sent for AI summarization and then forwarded to Telegram, but it does not provide a clear privacy warning or require explicit informed consent for transmitting potentially sensitive mailbox data to third-party services. In the context of an email-monitoring skill, this increases the risk of accidental disclosure of confidential, personal, or regulated information.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 120)May include surrounding context.

To check for new mail every 5 minutes and push to Telegram automatically:

bash
crontab -e

Add:

Static analysis

No suspicious patterns detected.