Back to skill

Security audit

查询高驰(COROS)运动手表的跑步运动数据

Security checks for vulnerabilities and agentic risk

Overview

This COROS fitness-data skill appears purpose-aligned, but it should be reviewed because it asks users to store and print a reusable password-derived secret while accessing private account activity data.

Install only if you are comfortable giving the skill access to your COROS account activity. Treat COROS_PASSWORD as a real password-equivalent secret, avoid printing it, do not commit scripts/.env, prefer a secret manager or protected environment variables, and rotate your COROS password if the hash is exposed. Review or update the npm dependencies and lockfile provenance before using it in a sensitive environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:52
Finding
Reusable COROS Credential Exposed Through Weak Storage and Logging Guidance<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:19-23`, `SKILL.md:52-58`, `scripts/.env:1-3`, `scripts/util.js:8-10`, `scripts/coros.js:42-49` **Vulnerability Type**: Reusable credential exposure and insecure secret handling **Risk Level**: Medium ### Vulnerable Code `scripts/util.js:8-10`: ```js let genHashedPassword = (password) => { const hashedPassword = createHash("md5").update(password).digest("hex"); return hashedPassword; }; ``` `SKILL.md:52-58`: ```js import { genHashedPassword } from "./util.js"; const hashedPassword = genHashedPassword("your_plain_password"); console.log(hashedPassword); // Output the MD5-hashed password for COROS_PASSWORD ``` `scripts/.env:1-3`: ```env # COROS account configuration COROS_ACCOUNT=xxx COROS_PASSWORD=xxx ``` `scripts/coros.js:42-49`: ```js const response = await axios.post( COROS_URLS.LOGIN_URL, { account: this.account, accountType: 2, pwd: this.password, }, { headers: DEFAULT_HEADERS, timeout: 60000 }, ); ``` ### Technical Analysis The generated MD5 value is transmitted directly as the `pwd` login parameter. It therefore functions as a reusable password-equivalent credential rather than merely as a non-reversible password-verification record. MD5 is a fast, unsalted hash and is unsuitable for protecting passwords. More importantly, because the COROS endpoint accepts the hash itself for authentication, an attacker may not need to recover the original plaintext password: possession of the hash may be sufficient for replay. The documentation recommends storing this credential in a project-local `.env` file and demonstrates printing it to standard output. This can expose the credential through: - Accidental source-control commits. - Terminal scrollback and shell-session capture. - CI/CD logs. - Process output collected by monitoring systems. - Backups or copies of the project directory. - Excessively permissive local file permissions. The checked-in `.env` contains ...[truncated 1454 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all examples that print the MD5 credential: ```js const hashedPassword = genHashedPassword(password); // Do not log hashedPassword. ``` 2. Treat the MD5 value as a full password-equivalent secret in all documentation and code. 3. Prefer an official OAuth, scoped API-token, or device-authorization mechanism if COROS provides one. 4. Store credentials in an operating-system keychain, encrypted secret manager, or CI/CD secret store rather than a project-local file. 5. If `.env` support must remain: - Add `.env` and `scripts/.env` to `.gitignore`. - Distribute only a placeholder `.env.example`. - Restrict permissions to the owning user, such as mode `0600`. - Add secret scanning to commits and CI pipelines. 6. Minimize token lifetime and clear in-memory credential references when they are no longer needed. 7. Never include credentials or access tokens in errors, telemetry, debug output, or request logs. 8. Document credential rotation procedures for users who may already have exposed the hash. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/package-lock.json:15
Finding
Dependency Lockfile Uses a Non-Canonical Third-Party Package Mirror<![CDATA[ ## Vulnerability Details **File Location**: `scripts/package-lock.json:15-29` and additional `resolved` entries through line 290 **Vulnerability Type**: Third-party dependency provenance and supply-chain risk **Risk Level**: Low ### Vulnerable Code `scripts/package-lock.json:15-29`: ```json "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://mirrors.tencent.com/npm/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { "version": "1.13.6", "resolved": "https://mirrors.tencent.com/npm/axios/-/axios-1.13.6.tgz", "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } } ``` Equivalent `https://mirrors.tencent.com/npm/` URLs are used for the other locked dependencies. ### Technical Analysis The lockfile directs package installations to a third-party mirror instead of the canonical npm registry. This expands the software supply-chain trust boundary: package availability and provenance depend on the mirror as well as npm and the package maintainers. The lockfile includes SHA-512 integrity values, which substantially mitigates undetected artifact substitution. A compromised mirror alone generally cannot replace a package without causing an integrity-check failure. Successful malicious substitution would normally also require modification of the lockfile or its integrity metadata, compromise during initial lockfile generation, or another failure in the package-installation trust chain. No malicious dependency, install script, typosquatted package, or dependency-confusion behavior was identified in the reviewed files. This finding concerns avoidable provenance risk rather than evidence that the listed packages are malic ...[truncated 1268 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure npm to use the canonical registry: ```bash npm config set registry https://registry.npmjs.org/ ``` 2. Regenerate and review the lockfile using the canonical registry: ```bash rm -rf node_modules package-lock.json npm install ``` 3. Verify that regenerated `resolved` entries use trusted registry URLs and retain SHA-512 integrity metadata. 4. Use `npm ci` in automated builds to enforce the reviewed lockfile. 5. Pin reviewed dependency versions where predictable builds are required rather than relying only on broad semver ranges. 6. Run dependency and provenance checks in CI, including `npm audit` and an appropriate software-composition-analysis tool. 7. Protect `package-lock.json` with mandatory code review and branch protections. 8. Consider generating an SBOM and verifying package signatures or provenance attestations where supported. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Credential Access

High
Category
Privilege Escalation
Content
import { genHashedPassword } from "./util.js";

const hashedPassword = genHashedPassword("your_plain_password");
console.log(hashedPassword); // 输出 MD5 加密后的密码,填入 .env 的 COROS_PASSWORD
```

### 计算某时间段总跑量
Confidence
94% confidence
Finding
The skill explicitly handles a reusable password equivalent by generating an MD5 hash for storage in .env and then using it to authenticate to the COROS API. MD5 is not appropriate for password protection, and if this hash functions as a login secret, disclosure of the .env value can enable credential replay or offline cracking against the user's account.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
90% confidence
Finding
The lockfile pins axios 1.13.6, and the static finding reports multiple known advisories affecting that version, including SSRF- and prototype-pollution-related issues. In a skill that queries external COROS data over HTTP, a vulnerable HTTP client is directly relevant because it may process attacker-influenced URLs, redirects, headers, or proxy settings.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
81% confidence
Finding
form-data 4.0.5 is flagged for CRLF injection via unescaped multipart field names and filenames. If any part of this skill uploads data or forwards user-controlled fields to external services, an attacker may be able to manipulate multipart boundaries or inject crafted headers, potentially altering downstream requests.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding
The package explicitly depends on axios 1.13.6, which the finding reports as having multiple known advisories, including SSRF-related and prototype-pollution-assisted attack paths. In a skill that retrieves external COROS data, HTTP client behavior is security-sensitive, so a vulnerable axios version can materially increase risk of request manipulation, credential leakage, or abuse of outbound network access depending on how the library is used elsewhere in the skill.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill documentation indicates use of environment-stored COROS credentials and account login, but it does not declare any explicit tool scope or permission boundary. This weakens reviewability and least-privilege guarantees, making it easier for a runtime or operator to expose secrets or enable broader capability use than users expect.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs users to supply COROS account identifiers and a password-derived value, but provides no warning about the sensitivity of those credentials or the risks of storing them in local environment files. Users may incorrectly assume this is low risk and store long-lived account secrets insecurely or share them across systems.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code posts COROS account credentials to a remote service during login, and later uses the authenticated client to retrieve activity data. While these network operations are central to the skill's purpose, the file provides no user-facing warning, confirmation, or explicit disclosure that credentials and personal activity data will be sent to external endpoints.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The `accept-language` header is fixed to `zh-CN,zh;q=0.9`, which imposes a specific language/locale setting. Under the policy, forcing a locale without user opt-in or documented justification is a natural-language policy concern.

Known Vulnerable Dependency: follow-redirects==1.15.11 — 1 advisory(ies): CVE-2026-40895 (follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Ta)

Low
Category
Supply Chain
Confidence
84% confidence
Finding
follow-redirects 1.15.11 is reported as leaking custom authentication headers across cross-domain redirects. Because this skill likely calls third-party APIs and may carry bearer tokens or session headers to access user fitness data, a redirect-based header leak could expose credentials to an attacker-controlled domain.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "ISC",
  "description": "",
  "dependencies": {
    "axios": "^1.13.6",
    "dotenv": "^17.3.1"
  },
  "type": "module"
Confidence
90% confidence
Finding
The dependency on axios uses a caret range (^1.13.6), which permits automatic installation of future patch and minor releases rather than a fully fixed version. This weakens supply-chain reproducibility and can unexpectedly introduce vulnerable or malicious code if an upstream release is compromised or regresses security.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"description": "",
  "dependencies": {
    "axios": "^1.13.6",
    "dotenv": "^17.3.1"
  },
  "type": "module"
}
Confidence
88% confidence
Finding
The dotenv dependency is also specified with a caret range (^17.3.1), so builds are not fully deterministic and may silently consume newer upstream releases. While this is not direct code execution by itself, it increases supply-chain risk and makes auditing and incident response harder.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This file contains natural-language comments and console output exclusively in Chinese, which imposes a specific language/locale without any visible opt-in or alternative. Under the policy, hard-coded language constraints can be a natural-language policy violation when no user choice is offered.

Static analysis

No suspicious patterns detected.