Back to skill

Security audit

Keep 健康记录

Security checks for vulnerabilities and agentic risk

Overview

This skill has a legitimate health-logging purpose, but it handles sensitive health data, images, and Keep credentials with broad activation and under-scoped upload and persistence behavior.

Review carefully before installing. Use this only if you are comfortable sending health records and selected images to Keep's MCP service, storing a Keep bearer token locally under ~/.keepai/.env, and allowing the skill to auto-trigger on broad health-logging phrases. Prefer a version that narrows activation, confirms before uploading images or saving sensitive records, requires HTTPS and trusted upload hosts, avoids temp-directory fallback, and persists tokens without command-line exposure.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/persist_auth.js:28
Finding

<![CDATA[Bearer Token Exposed Through Process Command-Line Arguments]]>

Content
View full analysis
a.startsWith(`--${name}=`)); if (inline) return inline.slice(name.length + 3); const idx = process.argv.findIndex((a) => a === `--${name}`); if (idx >= 0) return process.argv[idx + 1] || ""; return ""; } function hasFlag(name) { return process.argv.includes(`--${name}`); } function main() { if (hasFlag("clear")) { const { cleared } = clearCredentials(); emit("auth_cleared", { cleared }); return; } const token = String(readArg("token") || "").trim(); const username = String(readArg("username") || "").trim(); if (!token) { emit("error", { message: "缺少 --token 参数(或使用 --clear 清除凭证)" }); process.exitCode = 1; return; } const exp = decodeJwtExp(token); const { username: persistedUsername } = persistCredentials({ token, exp, username }); emit("auth_persisted", { exp, username: persistedUsername || username }); } ``` The prescribed invocation is: ```bash node {baseDir}/scripts/persist_auth.js --token='' --username='' ``` ### Technical Analysis The authentication bearer token is supplied as a command-line argument and read from `process.argv`. Command-line arguments are not an appropriate secret transport. Depending on the operating system, runner, and logging configuration, they may be exposed through: - Process inspection interfaces such as `/proc//cmdline`. - Process-monitoring utilities available to the same user or other authorized local users. - Agent execution logs, debug traces, shell audit systems, or command histories. - Crash reports and observability systems that record complete command lines. The documentation correc ...[truncated 1242 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/put-upload.js:78
Finding

<![CDATA[Shared Temporary-Directory Basename Fallback Can Upload an Attacker-Planted File]]>

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/put-upload.js:138
Finding

<![CDATA[Image Uploader Accepts Arbitrary HTTP Destinations and Unrestricted Headers]]>

Content
View full analysis
{ if (parsed[key] !== undefined && parsed[key] !== null) { headers[key] = String(parsed[key]); } }); } if (contentType && !Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) { headers["Content-Type"] = contentType; } return headers; } ``` ```javascript function uploadFile({ uploadUrl, headers, filePath, size }) { const parsedUrl = new URL(uploadUrl); const client = parsedUrl.protocol === "https:" ? https : http; return new Promise((resolve, reject) => { const request = client.request( parsedUrl, { method: "PUT", headers: { ...headers, "Content-Length": String(size), }, }, (response) => { const chunks = []; response.on("data", (chunk) => chunks.push(chunk)); response.on("end", () => { const body = Buffer.concat(chunks).toString("utf8"); resolve({ statusCode: response.statusCode || 0, headers: response.headers, body, }); }); }, ); request.on("error", (error) => { reject(error); }); const fileStream = fs.createReadStream(filePath); fileStream.on("error", (error) => { request.destroy(error); }); fileStream.pipe(request); }); ...[truncated 2636 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (39)

Context-Inappropriate Capability

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code resolves a user-supplied file path, falls back across temp directories, stages the file, and uploads its contents via HTTP or HTTPS PUT to any provided URL. That enables arbitrary local file exfiltration to attacker-controlled endpoints, which is especially dangerous in a skill handling highly sensitive personal health information.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill processes local image files and uploads them to URLs obtained at runtime, including temporary staging and custom headers. In the context of sensitive health logging, broad local file access plus network upload can enable accidental exfiltration of unrelated local files or over-collection of sensitive medical images if file selection and destination validation are not tightly constrained.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The skill processes local image files and uploads them to URLs obtained at runtime, including temporary staging and custom headers. In the context of sensitive health logging, broad local file access plus network upload can enable accidental exfiltration of unrelated local files or over-collection of sensitive medical images if file selection and destination validation are not tightly constrained.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill processes local image files and uploads them to URLs obtained at runtime, including temporary staging and custom headers. In the context of sensitive health logging, broad local file access plus network upload can enable accidental exfiltration of unrelated local files or over-collection of sensitive medical images if file selection and destination validation are not tightly constrained.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill processes local image files and uploads them to URLs obtained at runtime, including temporary staging and custom headers. In the context of sensitive health logging, broad local file access plus network upload can enable accidental exfiltration of unrelated local files or over-collection of sensitive medical images if file selection and destination validation are not tightly constrained.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill processes local image files and uploads them to URLs obtained at runtime, including temporary staging and custom headers. In the context of sensitive health logging, broad local file access plus network upload can enable accidental exfiltration of unrelated local files or over-collection of sensitive medical images if file selection and destination validation are not tightly constrained.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
3. **处理图片(如有)**:先 `get_upload_url` 拿预签名 URL,再用 `scripts/put-upload.js` 执行 PUT 上传。该脚本会先把源图片复制到固定目录(默认 `~/.keepai/tmp`,可用 `KEEP_UPLOAD_TMP_DIR` 覆盖),再发起上传;2xx 视为成功

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest explicitly says to activate even when users do not mention Keep and lists very common logging-style utterances such as meals, weight, sleep, and generic phrases like '帮我记一下'. These broad triggers can cause unintended activation on ordinary health conversation, leading to collection or transmission of sensitive health data without clear user intent to use this specific skill.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The tag list includes many generic Chinese terms tied to everyday speech, such as '记一下', '登记', '打卡', '吃了', '喝了', '睡了', and '运动'. In a health skill, these broad triggers are especially sensitive because they can match routine conversation about diet, sleep, exercise, or menstrual cycle and route intimate health data to the skill unexpectedly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This script is a generic file staging and upload utility that accepts an arbitrary local file path and an arbitrary upload URL, which is unrelated to the stated health-recording purpose of the skill. In a health-data skill context, bundling such a general exfiltration-capable helper materially increases risk because it can be used to move sensitive local files, including health records, to remote infrastructure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README explicitly states that MCP server configuration and later authentication tokens are written to ~/.keepai/.env, but it does not clearly warn users that persistent local credentials will be stored on disk. For a health-recording skill handling sensitive personal data, silent credential persistence increases the risk of unintended disclosure via backups, shared accounts, endpoint compromise, or user misunderstanding about where secrets are kept.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README describes uploading user images to a presigned URL and sending health-record data to a remote MCP service, but does not present a clear privacy or data-transmission warning. Because this skill processes highly sensitive health information, users should be explicitly informed that text and images may leave the local device and be transmitted to external services; without that transparency, the privacy risk is materially higher in this context.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares access to environment-provided secrets via ${env:keep_auth_token} and operational scripts, but does not define an explicit tool or permission scope limiting what capabilities the runner may expose. In a skill that handles authentication and uploads health-related data, missing scope boundaries increases the blast radius if the runner grants broader access than intended.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Broad triggers like “帮我记一下” and “记录一下” can cause the skill to activate on ambiguous everyday speech, increasing the chance of collecting or transmitting sensitive information without clear user intent to use Keep. Because this skill handles personal health data, over-triggering is more dangerous than in a low-sensitivity domain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation rule “任何健康数据录入行为” is so broad that it may capture messages where the user is discussing, analyzing, or drafting health information rather than consenting to save it. In a health context, such overbroad activation risks unauthorized logging of sensitive personal data and unnecessary authentication or upload prompts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The display name and description prominently use Chinese examples and trigger phrases, but the manifest does not state that the skill is region-specific or offer users a language choice. This can amount to an implicit locale/language constraint in activation behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The comments explicitly state that the script removes the skill's deployment from runner directories using rm -rf semantics. Deleting deployment artifacts from external runner environments is an operational/package-management capability that is not justified by a skill whose stated purpose is helping users log personal health data.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for recording health information such as diet, weight, exercise, sleep, and menstrual cycle. This file instead invokes undeployment logic to remove the skill from OpenClaw/Hermes runner skills directories, which is package lifecycle/installation behavior rather than user health-data recording behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file documents a full QR-based authentication and token persistence workflow even though the skill’s declared purpose is recording health data. Expanding behavior beyond the manifest increases privilege and data-handling scope, creating unnecessary access to account credentials and making abuse or over-collection more likely if the skill is misused or compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The template instructs users to reply with a specific Chinese phrase, and elsewhere the manual lists only Chinese trigger examples for manual confirmation. This creates a locale-specific interaction requirement without documenting user choice or providing equivalent alternatives in other languages.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instructions persist authentication material to ~/.keepai/.env, including a bearer token and expiry metadata, which creates a local secret at rest that may be readable by other local processes, backups, logs, or users depending on system configuration. Because this skill handles sensitive health-related actions, compromise of the stored token could enable unauthorized access to the user’s Keep account and associated personal data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instructions tell the agent to obtain a presigned URL and directly upload a local image to object storage, then pass the resulting CDN URL into the health-recording tool, but they do not require clear user consent or disclosure about external transmission and temporary local copying. Because this skill handles sensitive health data, silent upload of user images can expose highly private information beyond what a user may expect from a simple logging interaction.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documented upload flow allows the agent to operate on local file paths and, if the provided path is invalid, to probe multiple fallback directories such as ~/.keepai/tmp, /tmp, and /var/tmp by filename. In a health-recording skill, this expands access from user-supplied health data to broader local filesystem discovery, which can accidentally capture or upload the wrong sensitive image if a matching filename exists in those locations.

Content

No source excerpt is available for this finding.