Back to skill

Security audit

Jd Link Converter

Security checks for vulnerabilities and agentic risk

Overview

The skill does the advertised JD link conversion, but its short-link resolver can follow redirects to unvalidated network destinations.

Install only if you are comfortable with the agent making outbound requests to resolve JD short links. Prefer using direct item.jd.com/item.m.jd.com links or product IDs in sensitive environments, and avoid running the short-link resolver where it can reach internal services unless redirect validation is added.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/jd_link_converter.py:41
Finding

Unvalidated Redirect Following Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/jd_link_converter.py, lines 41-93
Vulnerability Type: Server-Side Request Forgery through unvalidated redirect destinations
Risk Level: Medium

The converter restricts the initial short URL to 3.cn or u.jd.com, but it does not apply equivalent validation to subsequent redirect destinations.

python
current_url = url
for _ in range(max_redirects):
    try:
        req = urllib.request.Request(
            current_url,
            method="GET",
            headers={
                "User-Agent": mobile_ua,
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                "Accept-Language": "zh-CN,zh;q=0.9",
            },
        )
        # Do not automatically follow redirects; handle each hop manually
        class NoRedirect(urllib.request.HTTPRedirectHandler):
            def redirect_request(self, req, fp, code, msg, headers, newurl):
                return None

        opener = urllib.request.build_opener(NoRedirect, urllib.request.HTTPHandler)
        try:
            resp = opener.open(req, timeout=10)
            final_url = resp.url
            resp.close()
            # Return immediately if a product page has been reached
            if "item.m.jd.com" in final_url or "item.jd.com" in final_url:
                return final_url
            current_url = final_url
        except urllib.error.HTTPError as e:
            if e.code in (301, 302, 303, 307, 308):
                location = e.headers.get("Location", "")
                if location:
                    # Handle relative paths
                    if location.startswith("/"):
                        from urllib.parse import urljoin
                        location = urljoin(current_url, location)
                    if "item.m.jd.com" in location or "item.jd.com" in location:
                        retur
...[truncated 3725 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the initial URL and every redirect destination with urllib.parse.urlsplit; never validate URLs using substring checks.
  2. Require HTTPS for the initial URL and all redirects.
  3. Allowlist the exact hostnames required for the conversion workflow, such as 3.cn, u.jd.com, item.m.jd.com, and item.jd.com. Reject user-info components, unexpected ports, malformed hostnames, and hostname suffix tricks.
  4. Resolve every destination hostname before making a request. Reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses using Python's ipaddress module.
  5. Revalidate every redirect hop, including relative redirects after resolving them with urljoin.
  6. Prevent DNS rebinding by connecting only to an already validated resolved address where practical, while preserving and separately validating the intended HTTP host and TLS identity.
  7. Remove the automatic-redirect fallback or use the same no-redirect handler and validation routine for every hop.
  8. Restrict destination ports to the expected HTTPS port and retain strict redirect-count and timeout limits.
  9. Add tests covering redirects to 127.0.0.1, ::1, RFC1918 networks, link-local ranges such as 169.254.0.0/16, encoded or alternative IP representations, non-HTTPS schemes, hostname suffix tricks, and redirect chains that become unsafe after an initially valid hop.
  10. Run the converter in a network-restricted sandbox that cannot reach cloud metadata services or internal administrative networks.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (10)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly states that short-link conversion requires network access and automatic parsing, but it does not warn that user-supplied JD links will be sent to external JD-controlled domains to follow redirects. In an agent context, users may paste links expecting local normalization only, so the undocumented network transmission creates a privacy and transparency issue rather than direct code-execution risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to perform HTTP resolution of user-supplied short links and explicitly references network-capable behavior, but it does not declare any tool scope or allowed-tools restriction. This creates an authorization gap: the runtime may permit broader-than-intended network access or make security review and enforcement of least privilege difficult, especially because the input is attacker-controlled URLs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

SQP-3 applies to natural-language policy issues in any file type, including markdown. The README consistently presents the skill interface and activation examples only in Chinese, and the Agent trigger examples are Chinese-only, which may amount to a forced language/locale assumption when no opt-in or justification is provided.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: wheel has 4 known advisory(ies) (CVE-2026-24049 (Wheel Affected by Arbitrary File Permission Modification via Path Traversal in w); CVE-2022-40898 (pypa/wheel vulnerable to Regular Expression denial of service (ReDoS)); CVE-2022-40898 (An issue discovered in Python Packaging Authority (PyPA) Wheel 0.37.1 and earlie) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language description is written entirely in Chinese and does not indicate that users can choose another language or that the skill is intentionally limited to a Chinese-speaking audience. Per the policy, forcing a specific language without user opt-in can be a locale/language policy violation.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file presents all instructions and examples exclusively in Chinese, which can constitute a language/locale policy violation when no user opt-in or scope justification is provided. The content does not indicate that the skill is region-specific or that users may choose another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request header sets "Accept-Language" to "zh-CN,zh;q=0.9", which imposes a specific language/locale preference in network interactions. Under the policy, locale constraints should be optional, user-selected, or clearly justified as region-specific; this file does not provide such opt-in or justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The usage text at L200 and comment at L211 state that the tool supports reading URLs from stdin via a pipe. However, when no command-line arguments are provided, the code exits immediately at L198-L207, so the stdin-handling branch at L212-L213 is unreachable in that scenario.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.