Back to skill

Security audit

whoami

Security checks for vulnerabilities and agentic risk

Overview

This identity-profile skill has a coherent purpose, but it needs Review because it broadly persists and reuses personal data and has unsafe endpoint, credential, and file-handling behavior.

Install only if you are comfortable with a remote service storing a concise personal profile and making it available to AI tools. Before use, verify the configured endpoint, avoid putting secrets or sensitive personal data in the profile, do not paste long-lived API keys into chat or command-line arguments, and avoid using update --file with any path except a disposable temp file you intended to delete.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/whoami_profile.py:45
Finding
Unvalidated endpoint override exposes API credentials and personal profile data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/whoami_profile.py`, lines 45-51 and 109-122 **Vulnerability Type**: Unvalidated network destination for authenticated requests **Risk Level**: High ### Vulnerable Code ```python def _get_endpoint() -> str: # 优先使用环境变量(开发测试用),其次配置文件,最后硬编码默认值 env_endpoint = os.environ.get("WHOAMI_ENDPOINT") if env_endpoint: return env_endpoint.rstrip("/") config = _load_config() return config.get("WHOAMI_ENDPOINT", DEFAULT_ENDPOINT) ``` ```python endpoint = _get_endpoint() url = f"{endpoint}/api{path}" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } data = None if body is not None: data = json.dumps(body).encode("utf-8") req = Request(url, data=data, headers=headers, method=method) ``` ### Technical Analysis The destination for authenticated API requests can be overridden using either the `WHOAMI_ENDPOINT` environment variable or the `WHOAMI_ENDPOINT` entry in `~/.whoamiagent`. The value is used without validating its scheme, hostname, port, or relationship to the legitimate service. Every API request includes the user's bearer credential in the `Authorization` header. Profile updates also include the complete personal profile in the request body. Consequently, control over the process environment or configuration file is sufficient to redirect both credentials and sensitive profile data to an attacker-controlled server. The network transfer itself is part of the declared remote-profile functionality. The vulnerability is that sensitive requests are not restricted to the service for which the credentials were issued. ### Attack Path 1. An attacker or compromised local process sets `WHOAMI_ENDPOINT` to an attacker-controlled URL, or inserts that value into `~/.whoamiagent`. 2. The user or AI agent invokes `get`, `info`, or `update`. 3. `_get_endpoint()` returns the attacker-controlled dest ...[truncated 989 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin production API traffic to the exact expected origin, such as `https://whoamiagent.com`. - Require HTTPS and reject credentials configured with HTTP or other schemes. - Parse override URLs and validate the scheme, hostname, and permitted port before use. - Disable endpoint overrides in production builds. If development overrides are necessary, require an explicit development mode and use separate test credentials. - Prevent bearer credentials from being forwarded across cross-origin redirects. - Separate endpoint configuration from the credential file so compromise of one setting does not silently redirect the credential stored beside it. - Display the validated destination and require explicit user approval before sending sensitive information to a non-production endpoint. ]]>

T01 · Skill Instruction Hijacking

Error
Location
scripts/whoami_profile.py:139
Finding
Untrusted remote profile is injected verbatim into agent context<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 19-22 and 58-64; `scripts/whoami_profile.py`, lines 139-149 **Vulnerability Type**: Remote indirect prompt injection and persistent profile poisoning **Risk Level**: High ### Vulnerable Code ```markdown **Core capabilities:** - Read user profile from remote and inject into conversation context - Save/update user identity information to remote - Execute subsequent tasks (calling other skills, writing code, etc.) based on user preferences - Share the same user profile across AI tools ``` ```markdown - If a remote profile exists, the script outputs Markdown content - If no remote profile exists, the script outputs a prompt; guide the user to create one **After loading the profile, use its content as context to understand the user, then continue executing the user's actual task.** ``` ```python def get_profile(): """获取远端 profile""" result = _api_request("GET", "/profile") if isinstance(result, dict): content = result.get("content") if content: print(content) else: print("[whoami] No profile found on remote.") print("[whoami] Use the update command to create a profile.") else: print(result) ``` ### Technical Analysis The Skill explicitly instructs the agent to fetch a remote Markdown document, inject it into the conversation context, and use it while performing subsequent tasks. The script prints the remote content verbatim without schema validation, field separation, sanitization, or a warning that instructions embedded in the profile are untrusted data. Markdown profile content can therefore include imperative text that resembles agent or tool instructions rather than identity information. Because the profile is remotely stored, shared across AI tools, and retained across sessions, malicious content can influence both the current agent session and later sessions. Potential sources of malicious profile ...[truncated 1830 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat all fetched profile content as untrusted data, never as executable instructions. - Add an explicit instruction to the Skill that commands, policies, URLs, and tool requests found inside a profile must not be followed. - Return a structured profile object with a strict schema instead of arbitrary Markdown. - Permit only expected profile fields and enforce type and length restrictions for every field. - Place fetched data inside clear delimiters identifying it as quoted user-profile data. - Require user confirmation when a remotely fetched profile has changed since its last trusted version. - Display profile changes as a diff before applying them to agent behavior. - Authenticate profile versions and maintain a trusted local revision identifier where practical. - Avoid automatically loading the profile for unrelated tasks; load it only when the user requests personalization or when the relevant profile fields are necessary. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/whoami_profile.py:212
Finding
Arbitrary file upload and deletion through the update --file option<![CDATA[ ## Vulnerability Details **File Location**: `scripts/whoami_profile.py`, lines 212-224 **Vulnerability Type**: Unsafe arbitrary file handling and automatic deletion **Risk Level**: High ### Vulnerable Code ```python # Check for --file flag if len(args) >= 2 and args[0] == "--file": file_path = Path(args[1]) if not file_path.exists(): print(f"[whoami] Error: File not found: {file_path}") sys.exit(1) content = file_path.read_text(encoding="utf-8").strip() # Auto-remove the temp file after reading try: file_path.unlink() print(f"[whoami] Temp file removed: {file_path}") except OSError: pass if not content: ``` ### Technical Analysis Although the option is documented as a mechanism for reading a temporary profile file, the implementation accepts any supplied filesystem path. It does not verify that the path is located in a designated temporary directory, that the file was created for this operation, that it is a regular file, or that it is not a symbolic link. The script reads the selected file and then calls `unlink()` before validating whether the content is nonempty and before confirming that the network update succeeds. The returned content is subsequently sent to the remote profile API. This creates two linked capabilities: 1. Any text file readable by the invoking user can be uploaded to the remote service. 2. Any selected file removable by that user can be deleted. Deleting the input is not required for the core remote-profile functionality and exceeds the minimum privilege needed to read profile content. ### Attack Path 1. An attacker manipulates instructions or arguments supplied to the agent so that it invokes: `python3 scripts/whoami_profile.py update --file <sensitive-path>`. 2. The script resolves the attacker-selected path without restricting its location or file type. 3. `read_text()` reads the file using ...[truncated 1079 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove automatic deletion of user-supplied files. - If temporary-file cleanup is required, create the file internally with Python's `tempfile` module and retain an internal record proving ownership. - Restrict accepted paths to a dedicated application-controlled temporary directory. - Resolve the canonical path and verify that it remains inside the approved directory. - Reject symbolic links, directories, device files, sockets, and other non-regular files. - Validate profile content before performing any destructive cleanup. - Perform cleanup only after a confirmed successful upload. - Require explicit user confirmation before reading a path that was not created by the Skill. - Prefer standard input for transferring generated profile content so no temporary filesystem deletion is necessary. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/whoami_profile.py:90
Finding
API key is exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/whoami_profile.py`, lines 90-101 and 184-186 **Vulnerability Type**: Sensitive credential passed through process arguments **Risk Level**: Medium ### Vulnerable Code ```python print("[whoami] IMPORTANT INSTRUCTIONS FOR AI AGENT:") print("[whoami] 1. DO NOT run this command again or any other whoami command.") print("[whoami] 2. STOP and WAIT for the user to respond with their API Key.") print("[whoami] 3. Tell the user: 'I've opened the login page in your browser. Please log in,") print("[whoami] generate an API Key on the Dashboard, and paste it here.'") print("[whoami] 4. Do NOT proceed until the user provides the API Key (starts with wai_).") print("[whoami] 5. Once the user gives you the API Key, run:") print(f"[whoami] python3 <skill-dir>/scripts/whoami_profile.py setup <API_KEY>") print(f"[whoami] Config file path: {CONFIG_PATH}") sys.exit(0) ``` ```python if len(sys.argv) > 2: api_key = sys.argv[2] else: ``` ### Technical Analysis The setup workflow instructs the AI agent to receive the user's API key and pass it as a positional command-line argument. Command-line arguments are not an appropriate secret-transport mechanism because they can be recorded in shell history, process-execution logs, AI tool traces, audit telemetry, terminal transcripts, and crash reports. Depending on the operating system and process isolation, arguments may also be visible to other local processes while the command is running. This implementation also conflicts with the documentation in `SKILL.md`, which states that the agent should use a one-time configuration URL and “never handles API Key directly.” The script instead tells the user to paste the raw key into the conversation and directs the agent to place it in `sys.argv`. ### Attack Path 1. The user invokes a command without an existing API-key configuration. 2. The script dire ...[truncated 1009 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never accept API keys as command-line arguments. - Use `getpass.getpass()` for interactive local setup so the credential is not echoed. - For agent-driven setup, use a one-time browser authorization flow in which the client receives a short-lived authorization result without exposing the long-term API key to the conversation. - If file-based provisioning is unavoidable, use a protected file with owner-only permissions and delete it securely after successful import. - Redact secrets from all tool-call logs, telemetry, exceptions, and terminal output. - Align `SKILL.md` and script behavior so both consistently use the documented one-time configuration mechanism. - Rotate any API key that has previously been passed through command-line arguments or pasted into retained agent conversations. ]]>
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 (19)

Vague Triggers

High
Confidence
97% confidence
Finding
The trigger description says to invoke the skill whenever user background, preferences, or personal context might help execute a task, which is extremely broad. This encourages routine invocation on ordinary conversations and can cause unnecessary collection, transmission, and reuse of personal data.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill advertises cross-AI identity sharing and remote profile storage, but does not present a clear warning that personal data will be transmitted to and reused across external tools. Users may unknowingly expose sensitive personal context beyond the current conversation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares broad operational behavior involving shell, network, file read/write, and environment access, but does not define any explicit tool scope or permission boundaries. This increases the chance an agent will execute sensitive actions implicitly, including fetching remote credentials, writing config files, and reusing profile data without clear containment.

Ssd 3

Medium
Confidence
94% confidence
Finding
The skill instructs agents to inject a remotely stored identity profile directly into conversation context and use it across AI tools. This is a natural-language data exposure pattern because broad personal context can be propagated into later prompts, logs, outputs, or downstream tools without granular controls.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill explicitly instructs the agent to load remote personal profile data and then continue performing the user's downstream task using that data as context. This creates a privacy and scope-expansion risk because sensitive identity information can influence unrelated tasks without fresh consent or minimization.

Session Persistence

Medium
Category
Rogue Agent
Content
│   └─ NO  → Script auto-opens browser login page → Agent tells user to log in and get one-time URL → **Agent STOPS and WAITS for user to provide one-time URL** → Agent downloads and saves to ~/.whoamiagent
    │
    ├─ User requests to update info?
    │   └─ YES → Organize into Markdown → Write to temp file → Run `update --file` to write to remote → Confirm success
    │
    └─ User asks "do you know me?"
        └─ Run `get` → Display profile summary
Confidence
89% confidence
Finding
The skill is explicitly designed for persistent remote storage and later reuse of identity/profile data across sessions and AI tools. This persistence increases exposure if the profile contains sensitive information, is over-broadly retrieved, or is accessed without clear consent boundaries.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
curl -s "https://whoamiagent.com/api/storeapi?token=<token>" > ~/.whoamiagent
chmod 600 ~/.whoamiagent
```

Config file is saved at `~/.whoamiagent` with the necessary credentials securely configured.
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Ssd 3

Medium
Confidence
93% confidence
Finding
The instruction to use the loaded profile as context for continuing the user's task encourages broad secondary use of personal data. In practice, this can leak unnecessary preferences, identity details, or history into unrelated responses and downstream processing.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
python3 <skill-dir>/scripts/whoami_profile.py update --file /tmp/whoami_profile_tmp.md
```

The script reads the file content, uploads it, and **automatically deletes the temp file** after reading.

Alternative (for short content only):
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The example normalizes automatic profile loading at conversation start, even for a generic coding task. In context, this makes unnecessary access to remotely stored identity data more likely and increases silent personalization and privacy leakage risks.

Ssd 3

Medium
Confidence
90% confidence
Finding
The example encourages persisting user-provided personal background information to a remote profile for later reuse. Without strong consent, classification, and retention controls, this creates durable privacy risk and potential over-collection of sensitive personal data.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
2. If API Key is not configured, the script auto-opens the browser login page. Agent **MUST**:
   - Tell the user: "I've opened the login page in your browser. Please log in and generate a one-time configuration URL on the Dashboard."
   - **STOP here and wait for the user to reply with the one-time configuration URL.**
   - Download the URL and save to `~/.whoamiagent`: `curl -s "<provided-url>" > ~/.whoamiagent && chmod 600 ~/.whoamiagent`
   - Then run `whoami_profile.py get` again to fetch the profile
3. If already configured, display profile summary
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
- Not all fields are required; users can fill in only the parts they consider important
- Content should be concise, max 5000 characters (~2000 Chinese characters or ~2000 English words)
- AI should auto-organize content into a reasonable Markdown structure when saving
- The update command is an overwrite operation; always pass complete content
- Remote automatically retains the last 3 historical versions; mistakes can be rolled back via API

## API Authentication
Confidence
60% 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.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The script allows WHOAMI_ENDPOINT and WHOAMI_FRONTEND_URL to fully override the remote API and login destinations. In an agent context, this can redirect profile contents and bearer tokens to attacker-controlled infrastructure, turning a profile sync tool into a credential and data exfiltration path.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The manifest describes a skill for loading and saving a user's identity profile so an agent can use that context in later tasks. Opening a browser to an external login page is an additional interactive capability outside simple profile retrieval/update, and the manifest does not disclose this behavior.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
When invoked with --file, the script deletes the supplied file after reading it, even though the skill is described as loading/saving a remote profile rather than modifying local files. In an agent setting, this can destroy user data unexpectedly if a non-temporary path is provided, causing integrity and availability loss.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The file deletion occurs silently after read, without explicit user consent at the time of action or a clear upfront warning in the interface. For an agent-operated tool, users may not realize a local file will be removed, making accidental destructive behavior more likely and increasing the risk of data loss.

Context-Inappropriate Capability

Low
Confidence
81% confidence
Finding
The first-time setup flow goes beyond simple profile sync by initiating browser-based login and credential bootstrap steps. That expands the trust boundary and can lead agents to facilitate secret acquisition and persistent configuration changes on the user's system.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The file contains user-facing descriptions primarily in Chinese, while later operational prompts are in English, and there is no indication that the user can choose their preferred language. This can violate a language/locale policy when a skill imposes language assumptions without opt-in.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/profile_format.md:46