Back to skill

Security audit

中华05骨龄分析 RUS-CHN05

Security checks for vulnerabilities and agentic risk

Overview

The skill’s medical-analysis purpose is coherent, but it sends minors’ X-rays and personal health data to remote services with weak consent, host, upload, and credential safeguards.

Install only if you trust the慧龄云/pipitu service and can operate it under appropriate medical-data privacy controls. Require explicit consent before upload, use only the intended HTTPS host, avoid command-line password hashes, do not publish or log tokens, and review the partial PAT entries and dependency pinning before production use.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bone_age_api_client.py:47
Finding

Unrestricted API Host Allows Credential and Authentication Token Disclosure

Content
View full analysis

Vulnerability Details

File Location: scripts/bone_age_api_client.py:47-53, scripts/bone_age_api_client.py:63-65, scripts/bone_age_api_client.py:101-112, and scripts/bone_age_api_client.py:433; equivalent behavior exists in both example clients.
Vulnerability Type: Arbitrary authentication endpoint and missing transport validation
Risk Level: High

Vulnerable Code

python
def __init__(self, host: str):
    self.host = host.rstrip("/")
    self.token = None
    self.user = None
    self.tid = self._generate_tid()
    self.session = requests.Session()
    self.session.headers.update({"Content-Type": "application/json; charset=utf-8"})
python
def _url(self, path: str) -> str:
    return f"{self.host}{path}"
python
resp = self.session.post(
    self._url("/auth/local/login"),
    json={"username": username, "password": password_hash}
)
result = resp.json()
if result.get("ret"):
    data = result.get("data", {})
    self.token = data.get("token")
    self.user = data.get("user")
    self.session.headers.update({"token": self.token})
python
parser.add_argument("--host", required=True)

Equivalent configurable-host behavior appears at:

  • examples/third_party_integration.py:40-47, 66-74, and 198
  • examples/c_end_integration.py:39-46, 50-59, and 282

Technical Analysis

The client accepts an arbitrary API host and concatenates it directly with authentication and business endpoint paths. It does not require HTTPS, verify that the destination is the declared www.pipitu.net service, reject embedded URL credentials, restrict ports, or otherwise enforce a destination allowlist.

The password hash is not merely a non-sensitive digest. Because the remote service accepts the SHA-256 value directly as the password field, it is a reusable password-equivalent verifier. A hostile endpoint can capture it and replay it against the legi ...[truncated 1465 chars]

Remediation
View remediation

Remediation Suggestions

  • Hard-code or strictly allowlist https://www.pipitu.net for production use.
  • Parse the URL with a standard URL parser and reject:
    • Schemes other than HTTPS
    • Embedded usernames or passwords
    • Unexpected ports
    • IP-address literals
    • Subdomains or suffix matches that are not exact approved hosts
  • Disable cross-origin redirects for requests that carry credentials or tokens.
  • If development endpoints are required, place them behind an explicit development-only option and require interactive confirmation before transmitting credentials.
  • Separate authenticated and unauthenticated sessions so a token cannot accidentally be propagated to an unintended destination.
  • Prefer a challenge-based authentication protocol instead of treating an unsalted SHA-256 password digest as a reusable credential.
  • Add automated tests confirming that HTTP, lookalike domains, unexpected ports, and redirect-based destination changes are rejected.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bone_age_api_client.py:124
Finding

Unvalidated Presigned Upload URL Can Exfiltrate Minors' Medical Images

Content
View full analysis

Vulnerability Details

File Location: scripts/bone_age_api_client.py:124-146; equivalent upload logic appears in README.md:87-92, examples/third_party_integration.py:86-98, and examples/c_end_integration.py:69-81.
Vulnerability Type: Unrestricted sensitive-file upload destination
Risk Level: High

Vulnerable Code

python
resp = self.session.post(
    self._url("/service/signForBAImageUploadEasy"),
    json={"fileName": file_name},
    headers=self._auth_header()
)
result = resp.json()
if result.get("ret"):
    signed_url = result.get("data", {}).get("signedUrl", "")
return result
python
def upload_image(self, signed_url: str, file_path: str) -> bool:
    with open(file_path, "rb") as f:
        resp = requests.put(signed_url, data=f.read())
    if resp.status_code == 200:
        return True
    else:
        return False

The documented example contains the same trust model:

python
signed_url = resp.json()["data"]["signedUrl"]
with open("bone.jpg", "rb") as f:
    requests.put(signed_url, data=f.read())

Technical Analysis

The client reads the complete selected X-ray image and uploads it to any URL returned by the signing endpoint. It does not verify the URL scheme, destination hostname, expected Tencent COS bucket, region, path structure, or redirect behavior.

The declared protocol identifies the expected storage destination as the Tencent COS bucket pipitu-1255772158 in ap-chengdu. Restricting uploads to that approved storage boundary would still support the Skill's functionality. Trusting an arbitrary URL therefore exceeds minimum privilege.

This issue can be exploited through the unrestricted host behavior in the first finding, compromise of the signing service, response manipulation where transport protections are absent, or a server-side configuration error. The primary API client also performs the upload without a timeout.

...[truncated 1079 chars]

Remediation
View remediation

Remediation Suggestions

  • Parse and validate every presigned URL before opening the local image.
  • Require HTTPS and an exact approved Tencent COS hostname, bucket, region, and expected object-key prefix.
  • Maintain a narrowly scoped allowlist if the provider legitimately uses more than one storage hostname.
  • Disable redirects during upload or independently validate every redirect target.
  • Apply explicit connection and read timeouts.
  • Validate the input path, file extension, MIME type, magic bytes, and maximum file size before upload.
  • Stream the image rather than loading the entire file into memory.
  • Display the approved destination and obtain informed user consent before sending medical data.
  • Document retention, deletion, access control, regional storage, and third-party processing practices.
  • Avoid including patient identifiers in file names or object keys.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bone_age_api_client.py:433
Finding

Reusable Password Hashes and JWTs Are Exposed Through Process Arguments and Standard Output

Content
View full analysis

Vulnerability Details

File Location: scripts/bone_age_api_client.py:433-459; related command-line exposure exists in examples/third_party_integration.py:20-21, 200 and examples/c_end_integration.py:284.
Vulnerability Type: Sensitive authentication data exposure
Risk Level: High

Vulnerable Code

python
parser.add_argument("--host", required=True)
parser.add_argument("--username", required=True)
parser.add_argument("--password-hash", required=True)
python
if args.login_only:
    client.register()
    result = client.login(args.username, args.password_hash)
    print(json.dumps(result, ensure_ascii=False, indent=2))
    return

The documented example also encourages supplying the password-equivalent hash directly in the command line:

python
parser.add_argument(
    "--password-hash",
    default=os.getenv("BONE_AGE_PASSWORD_HASH")
)

Technical Analysis

Command-line arguments are frequently retained in shell history and may be visible through process inspection, job-control systems, telemetry, crash reports, or CI logs. The submitted SHA-256 value is accepted directly by the API and is therefore a reusable authentication secret.

In login-only mode, the client prints the entire login response. According to the documented protocol, this response includes data.token, user details, and token expiry information. Printing the unredacted response can expose a valid JWT in terminal logs, redirected files, CI output, or support bundles.

Environment variables reduce shell-history exposure but remain accessible to the process and can leak through diagnostics or deployment metadata. They are not a substitute for a managed secret mechanism.

Attack Path

  1. A user invokes the client with --password-hash or runs login-only mode.
  2. The password hash remains in shell history, appears in process metadata, or is captured by job logs.
  3. Login-only output writ ...[truncated 748 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the --password-hash option from normal operation.
  • Read authentication secrets using a non-echoing prompt, operating-system keychain, protected file descriptor, or managed secret store.
  • If environment variables remain supported, warn users about their exposure and limit them to controlled deployment environments.
  • Never print complete authentication responses.
  • Construct a safe output object containing only success status and a non-sensitive expiry timestamp.
  • Implement centralized redaction for fields named token, password, password_hash, cookie, and signedUrl.
  • Ensure exception messages and debug logging cannot serialize session headers or request bodies.
  • Rotate credentials and revoke tokens that may already have appeared in logs.
  • Set restrictive permissions and short retention periods for application and CI logs.
  • Use short-lived, narrowly scoped tokens and support explicit logout or token revocation.

T08 · Insecure Dependencies

Warning
Location
README.md:28
Finding

Unpinned Requests Dependency Creates a Non-Reproducible Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: README.md:28-31; the same unpinned installation instruction is repeated in scripts/bone_age_api_client.py:40-45, examples/third_party_integration.py:32-37, and examples/c_end_integration.py:28-33.
Vulnerability Type: Unpinned runtime dependency
Risk Level: Medium

Vulnerable Code

bash
pip install requests
python
try:
    import requests
except ImportError:
    print("Install the requests package with pip.")
    sys.exit(1)

Technical Analysis

The installation instructions resolve requests without a reviewed version constraint, lockfile, or package hash. Consequently, two installations performed at different times may receive different package versions and transitive dependencies.

Although requests is a well-known package and no malicious dependency is embedded in this project, unconstrained dependency resolution weakens reproducibility and permits a future compromised, incompatible, or unexpectedly changed release to enter the environment without further review. The dependency has direct access to authentication values, JWT headers, medical images, and patient information processed by the client.

Attack Path

  1. A user follows the documented pip install requests instruction.
  2. The package index resolves the latest available release and its transitive dependencies.
  3. A compromised or unexpectedly vulnerable release is installed.
  4. Package code executes during installation or when imported by the client.
  5. The compromised dependency reads or intercepts credentials, tokens, patient data, and X-ray uploads.

Impact Assessment

A compromised dependency executes with the same local privileges as the user running the client. It can access all in-process authentication and medical data, files readable by that user, and available network resources. This finding does not establish that the current requests package is ...[truncated 97 chars]

Remediation
View remediation

Remediation Suggestions

  • Add a dependency manifest with an explicitly reviewed version of requests.
  • Generate a lockfile that includes all transitive dependencies.
  • Require cryptographic hashes during installation, such as with pip install --require-hashes.
  • Install exclusively from the official package index or a controlled internal mirror.
  • Use an isolated virtual environment with minimal permissions.
  • Add automated dependency vulnerability scanning and a controlled update process.
  • Review dependency changes before publishing each Skill version.
  • Document the supported Python version so dependency resolution remains reproducible.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

2. 配置环境变量

bash
cp .env.example .env
# 编辑 .env 填入你的慧龄云(R)账号信息

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

bash
cp .env.example .env
# 编辑 .env 填入你的慧龄云(R)账号信息

3. 运行接入示例

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs the agent to collect sensitive personal and health-related information, including phone number, age, height, weight, parental heights, and menstruation status, but does not require clear upfront consent or explain that this data will be sent to an external third-party service. In a pediatric medical context, this creates substantial privacy and compliance risk, especially because the data concerns minors and includes health information.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill defines an external upload flow for wrist/hand X-ray images using a presigned URL and third-party processing, but it does not require explicit warning or consent before transmitting medical imagery off-platform. Because these are pediatric diagnostic images, undisclosed third-party upload materially increases privacy, confidentiality, and regulatory exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document displays partial PAT values for Gitee and GitHub and labels them as authentication material, which unnecessarily exposes credential fingerprints and signals that live secrets may be handled casually in documentation. Even partial token disclosure can aid social engineering, secret correlation, or encourage unsafe storage practices, especially in a repo tied to code publishing and distribution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The README is entirely presented in Chinese and does not indicate that language selection is optional or that the locale is constrained by a documented regional/compliance requirement. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README describes sending hand/wrist X-ray images and related personal data, but does not clearly warn users that sensitive medical and identifying data will be transmitted to a third-party remote service. In a pediatric medical context, this is privacy-relevant because users may unknowingly expose protected health information and family data without informed consent or retention/handling disclosures.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The API example shows obtaining a signed URL and uploading the image to it, but does not explicitly warn that the file leaves the local environment and is sent to external storage/service infrastructure. Because the content is medical imagery of minors, failure to disclose remote upload behavior increases the risk of accidental exposure and noncompliant handling of sensitive data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly performs network access and depends on environment-stored credentials, yet it declares no explicit tool scope or permission boundaries. In a medical-image workflow that uploads X-rays and uses account credentials, missing scope declarations increases the risk of unintended network access, silent secret use, and weak operator visibility into what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger examples include broad, conversational medical-image requests that may activate the skill on loosely related user inputs. In this skill, accidental activation is more serious because it can lead to collection of medical and personal data and initiation of third-party upload/login workflows without sufficiently deliberate user intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

该处明确指示报告“使用中文”,但文档没有提供用户选择其他语言的选项,也未说明该技能仅面向中文用户或特定地区使用。按照语言/地区政策要求,强制固定输出语言而无用户选择属于自然语言策略问题。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This client transmits highly sensitive data including child medical imaging, age, sex, height, parent heights, phone number, and optionally menstruation history to a remote service, but the script provides no explicit consent, privacy notice, data retention disclosure, or minimization controls. In a medical context involving minors, this increases legal and privacy risk because users may send regulated health and personal data without informed understanding of where it is processed or stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The example sends authentication credentials to a remote third-party endpoint without any explicit warning that credentials are being disclosed to an external service. Although remote login is expected for an integration client and the password appears pre-hashed, integrators may still unknowingly expose account credentials or reusable secrets to a third party, which is especially sensitive in a healthcare workflow tied to patient data access and billable actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code uploads a pediatric wrist X-ray to a third-party signed URL with no explicit consent, privacy notice, destination disclosure, or safeguards around handling protected health information. In a medical-imaging context, transmitting sensitive diagnostic images off-platform is security- and privacy-relevant because users or integrators may not realize the image is being sent to external storage/services, creating risk of unauthorized disclosure, regulatory noncompliance, and weak auditability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The report generator hardcodes a Chinese diagnostic report and the surrounding natural-language strings are exclusively Chinese, with no opt-in or language selection. This creates a language/locale policy issue because the skill enforces a specific output language rather than offering a user choice or documenting that the tool is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The protocol documents transmission of highly sensitive data—including pediatric wrist X-rays, sex, age, height, weight, parent heights, telephone numbers, and report history—to external services and cloud storage, but it does not include any privacy, consent, retention, or third-party sharing warning. In a medical context involving minors, this omission is dangerous because integrators may deploy the workflow without informing users or implementing required safeguards for health data and children’s personal data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The update guide instructs users to run clawhub skill publish and git push against a local skill directory without clearly warning that these commands upload the full local skill contents to third-party services. In a skill repository context, that omission can lead maintainers to accidentally publish embedded secrets, private medical logic, test data, or other sensitive files if the directory is not carefully sanitized before release.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manual reassessment path allows editing bone-stage inputs and resubmitting them for a new prediction, a capability not disclosed in the skill manifest. In a clinical workflow, undeclared alteration of diagnostic inputs can enable integrity issues, misleading outputs, or unauthorized manipulation of medical assessments beyond the user's expected operation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The client exposes a history-report retrieval function that goes beyond the manifest's described purpose of analyzing a currently uploaded X-ray and generating a report. In a medical context, this can expand access to prior patient reports and account-level data, increasing privacy and data-minimization risk if invoked without explicit user intent and authorization boundaries.

Content

No source excerpt is available for this finding.

Overly Broad Trigger

Low
Category
Trigger Abuse
Confidence
78% confidence
Finding

The trigger 骨龄 is very short and generic, making accidental activation plausible. In this skill's context, that matters because activation can lead into a workflow involving credentials, external uploads, and handling of sensitive medical data about minors.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest describes a medical-image analysis workflow for uploaded wrist X-rays and height prediction. In addition to that domain logic, this script pulls authentication material from process environment variables for API access, which is an operational convenience but not a user-facing capability implied by the stated purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The API description hard-codes sex handling as M/F with automatic conversion from Chinese "男"/"女", reflecting a locale-specific assumption. The document does not state that the skill is limited to a Chinese-only context or offer any language/locale choice, which can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module docstring, usage examples, and CLI help text are written entirely in Chinese, which imposes a language choice on users without any opt-in or alternative locale. The stated policy flags language or locale constraints when a skill forces a specific language without offering user choice.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Python code POSTs credential environment variables to an environment-controlled URL.

Critical
Code
suspicious.env_credential_access
Location
examples/c_end_integration.py:50

Python code POSTs credential environment variables to an environment-controlled URL.

Critical
Code
suspicious.env_credential_access
Location
examples/third_party_integration.py:51