Back to skill

Security audit

Gsdata

Security checks for vulnerabilities and agentic risk

Overview

This is a functional GSData API adapter, but it exposes credentials and remote account changes through under-scoped network and raw endpoint controls that need review before installation.

Review this before installing. Use only least-privileged GSData credentials, avoid custom base URLs, require an HTTPS allowlisted endpoint, disable or tightly restrict gsdata_raw, and manually confirm any warning-rule, ranking-group, account, or recipient-management operation before running it.

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
gsdata_adapter.py:24
Finding

Credential-Derived Authentication Material Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: gsdata_adapter.py:24, gsdata_adapter.py:203-213, gsdata_adapter.py:408-410, and gsdata_adapter.py:453-460
Vulnerability Type: Plaintext transmission of sensitive authentication material
Risk Level: High

Vulnerable Code

python
DEFAULT_BASE_URL = "http://databus.gsdata.cn:8888/api/service"
python
def make_sign(params: Dict[str, Any], app_secret: str) -> str:
    # GSData signature: md5(app_secret + "_" + sorted(kv concat) + "_" + app_secret)
    sorted_items = sorted(params.items(), key=lambda x: x[0])
    concat = "".join(f"{k}{v}" for k, v in sorted_items)
    raw = f"{app_secret}_{concat}_{app_secret}"
    return hashlib.md5(raw.encode("utf-8")).hexdigest()


def make_access_token(app_key: str, sign: str, router: str) -> str:
    return base64.b64encode(f"{app_key}:{sign}:{router}".encode("utf-8")).decode(
        "utf-8"
    )
python
sign = make_sign(params, self.app_secret)
token = make_access_token(self.app_key, sign, route)
headers = {"access-token": token}
python
def _request(
    self, method: str, params: Dict[str, Any], headers: Dict[str, str]
) -> requests.Response:
    # GSData gateway commonly accepts params in query/body against one base URL.
    if method == "POST":
        return requests.post(
            self.base_url, data=params, headers=headers, timeout=30
        )
    return requests.get(self.base_url, params=params, headers=headers, timeout=30)

Technical Analysis

The adapter defaults to an unencrypted http:// GSData endpoint. Every non-dry-run request includes an access-token containing the application key, a secret-derived MD5 signature, and the selected API route. Request parameters are also transmitted in either the URL query string or POST body.

Base64 is only reversible encoding and provides no confidentiality. Although the application secret itself is n ...[truncated 1665 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the default endpoint with an official HTTPS endpoint.
  2. Reject any base URL whose scheme is not https.
  3. Retain TLS certificate verification and do not introduce verify=False.
  4. Consider pinning or allowlisting the expected GSData hostname.
  5. Fail closed if HTTPS is unavailable rather than falling back to plaintext HTTP.
  6. If the GSData protocol supports it, migrate from MD5-based signing to a modern construction such as HMAC-SHA-256.
  7. Confirm that the server enforces short validity periods, nonces, timestamps, and replay protection for signed requests.
  8. Avoid placing sensitive query data in URL parameters where the API permits use of protected POST bodies.

T09 · Insecure Skill Coding Practices

Error
Location
gsdata_adapter.py:641
Finding

Unrestricted Base URL Override Can Redirect Authentication Material to an Attacker-Controlled Host

Content
View full analysis

Vulnerability Details

File Location: gsdata_adapter.py:641-644, gsdata_adapter.py:753-757, and gsdata_adapter.py:453-460
Vulnerability Type: Unvalidated credential destination and excessive network configurability
Risk Level: High

Vulnerable Code

python
parser.add_argument(
    "--base-url",
    default=os.getenv("GSDATA_BASE_URL", DEFAULT_BASE_URL),
    help="GSData gateway base URL",
)
python
adapter = GsDataAdapter(
    app_key=args.app_key or "DUMMY_APP_KEY",
    app_secret=args.app_secret or "DUMMY_APP_SECRET",
    base_url=args.base_url,
    mapping_path=Path(args.mapping),
)
python
def _request(
    self, method: str, params: Dict[str, Any], headers: Dict[str, str]
) -> requests.Response:
    # GSData gateway commonly accepts params in query/body against one base URL.
    if method == "POST":
        return requests.post(
            self.base_url, data=params, headers=headers, timeout=30
        )
    return requests.get(self.base_url, params=params, headers=headers, timeout=30)

Technical Analysis

The network destination can be replaced through either the --base-url command-line argument or the GSDATA_BASE_URL environment variable. No scheme, hostname, port, or path validation is applied before the adapter sends the access-token and user-supplied parameters to that destination.

As a result, a poisoned execution environment or unsafe command invocation can redirect credential-derived authentication material to an arbitrary server. Allowing unrestricted destinations is broader than necessary for the declared purpose of communicating with the GSData platform.

The application secret is not sent directly. However, the destination receives the application key, secret-derived signature, route, and request parameters contained in or accompanying the access token.

Attack Path

  1. An attacker gains influence over the process ...[truncated 1109 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the production endpoint to an official HTTPS GSData hostname.
  2. Validate the parsed URL before generating or transmitting authentication material.
  3. Enforce an allowlist for the scheme, hostname, port, and expected API path.
  4. Remove the environment override in production or require an explicit development-only mode.
  5. Never allow production credentials to be used when a custom endpoint is selected.
  6. Reject loopback, link-local, private-network, non-HTTPS, and unexpected redirect destinations unless specifically required and safely configured.
  7. Disable automatic cross-origin redirects for authenticated requests or strip authentication headers before any permitted redirect.
  8. Log the selected destination without logging credentials or access tokens so destination changes can be audited.

T09 · Insecure Skill Coding Practices

Warning
Location
gsdata_adapter.py:463
Finding

Raw API Interface Can Bypass Write Confirmation through Heuristic Route Classification

Content
View full analysis

Vulnerability Details

File Location: gsdata_adapter.py:396-405, gsdata_adapter.py:463-470, gsdata_adapter.py:677-689, and gsdata_adapter.py:792-801
Vulnerability Type: Incomplete authorization enforcement for potentially mutating requests
Risk Level: Medium

Vulnerable Code

python
if self._is_write_route(route) and not allow_write:
    return {
        "ok": False,
        "error": "WRITE_BLOCKED",
        "message": (
            "This route is considered write/high-risk. "
            "Pass allow_write=true after explicit confirmation."
        ),
        "route": route,
        "method": method,
    }
python
@staticmethod
def _is_write_route(route: str) -> bool:
    if "/warning/" in route:
        # warning module has both read and write; keep reads open
        if route.endswith(("/index", "/news", "/stats")):
            return False
        return True
    return any(s in route for s in WRITE_SUFFIX_HINTS)
python
p_raw = sub.add_parser("raw", help="Invoke arbitrary route via gsdata_raw")
p_raw.add_argument("--path", required=True)
p_raw.add_argument("--method", default="GET")
p_raw.add_argument("--params", help='JSON object, e.g. \'{"id":"123"}\'')
p_raw.add_argument("--params-file", help="Path to JSON object file")
p_raw.add_argument(
    "--param",
    action="append",
    default=[],
    help="Repeatable key=value param. Example: --param id=123",
)
p_raw.add_argument("--dry-run", action="store_true")
p_raw.add_argument("--allow-write", action="store_true")
python
if args.cmd == "raw":
    result = adapter.invoke(
        tool="gsdata_raw",
        action="call_any_endpoint",
        params=_merge_params(args.params, args.params_file, args.param),
        dry_run=args.dry_run,
        allow_write=args.allow_write,
        explicit_path=args.path,
        explicit_method=args.method,
    )
    
...[truncated 2172 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require --allow-write for every raw request, regardless of path or HTTP method.
  2. At minimum, treat all methods other than GET and HEAD as potentially mutating.
  3. Deny unknown raw routes by default and permit only routes present in trusted endpoint metadata.
  4. Replace substring matching with an explicit per-endpoint classification of read-only and mutating operations.
  5. Fail closed when an endpoint cannot be conclusively classified as read-only.
  6. Keep the raw interface disabled in normal agent use or place it behind a separate development option.
  7. Require explicit user confirmation containing the exact route, method, and material parameters before executing a mutating request.
  8. Add tests covering unknown paths, non-GET methods, redirects, and mutating routes whose names do not contain the current write suffix hints.
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 (12)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · gsdata_adapter.py (reported line 26)May include surrounding context.

python
DEFAULT_BASE_URL = "http://databus.gsdata.cn:8888/api/service"
DEFAULT_MAPPING_PATH = Path(__file__).with_name("gsdata_tool_mapping_v1.json")
DEFAULT_CREDS_PATH = Path.home() / ".config" / "gsdata" / "credentials.json"


ACCOUNT_PLATFORMS = {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · gsdata_adapter.py (reported line 699)May include surrounding context.

python
DEFAULT_BASE_URL = "http://databus.gsdata.cn:8888/api/service"
DEFAULT_MAPPING_PATH = Path(__file__).with_name("gsdata_tool_mapping_v1.json")
DEFAULT_CREDS_PATH = Path.home() / ".config" / "gsdata" / "credentials.json"


ACCOUNT_PLATFORMS = {

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

The adapter includes warning-rule management actions such as create, update, open, close, and recipient email modification, which are state-changing operations outside the stated query/search scope. Even with allow_write gating, the code still exposes administrative functionality that could alter alerts or notification settings if invoked.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The gsdata_raw path bypasses the curated high-level tool surface and allows callers to target arbitrary GSData routes. In a skill advertised as query-oriented, this materially expands capability and can be used to reach unintended read or write endpoints, undermining least privilege and review assumptions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is presented as query/search oriented, but the mapping exposes multiple state-changing endpoints for custom rank/group management, including add/delete group and account operations. This creates a capability mismatch: an agent invoked for benign data lookup could be induced to mutate persistent user data or account configuration, increasing the risk of unauthorized actions through prompt confusion or social engineering.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest emphasizes public opinion search, hot-topic analysis, rankings, and data queries, but the mapping also includes warning-rule administration, enable/disable actions, and notification-recipient management. These are privileged configuration operations unrelated to simple querying, so an attacker could abuse the skill’s broader-than-advertised authority to create surveillance rules, alter alerting behavior, or redirect notifications.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares access to sensitive capabilities through its design and instructions: it uses environment secrets, reads bundled files, and performs network requests, but it does not constrain tool scope with explicit permissions or allowed-tools metadata. In an agent environment, that increases the chance the skill can invoke broader-than-necessary capabilities or be misused through prompt injection or ambiguous orchestration, especially because it instructs the agent to execute a local adapter script against an external API.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are broad generic terms like '舆情', '热点', '榜单', and '关键词检索', which can match many ordinary user requests unrelated to this specific skill. In a multi-skill agent, that can cause unintended activation of a capability that reads env-backed credentials and performs external queries, increasing the risk of unnecessary data exposure, wrong-tool execution, or abuse via crafted prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The adapter sends caller-supplied parameters over HTTP(S) via requests.get/requests.post, but there is no print statement, confirmation prompt, or user-facing warning at the request point describing that input data will be transmitted to an external service. Because this is a code file and the operation involves network transmission of potentially user or system data, it meets the missing-warning criterion.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest frames the skill as a GSData query adapter and does not mention local credential discovery from environment variables or ~/.config/gsdata/credentials.json. While authentication may be needed for implementation, automatic access to local secrets is an additional capability not disclosed by the skill’s stated purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The credential resolution logic reads sensitive authentication material from GSDATA_APP_KEY/GSDATA_APP_SECRET and from ~/.config/gsdata/credentials.json, but the file provides no disclosure, confirmation, or user-facing notice that secrets will be accessed. Access to sensitive environment variables or credentials is explicitly in scope for missing-warning findings on code files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Adding or deleting email recipients for warning notifications is a state-changing capability that is not justified by the skill’s stated query-focused purpose. If misused, it could redirect sensitive alert content to unauthorized recipients or suppress legitimate monitoring by removing intended recipients, causing privacy leakage and operational blind spots.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.