Back to skill

Security audit

Realtime Creator Data (TikTok/IG/FB/YouTube)

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the advertised social-media enrichment, but it also has under-disclosed credential, endpoint, and persistent tracking behaviors that users should review before installing.

Install only if you are comfortable sending creator identifiers, content URLs, query terms, and possibly an API key to the configured gateway. Prefer a trusted HTTPS endpoint, avoid putting unrelated secrets in the .env file, do not allow untrusted callers to set SCRUMBALL_BASE_URL or override headers, and be aware the runner creates a persistent install ID that may need manual deletion.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:100
Finding

Mandatory Third-Party Promotional Output Triggered by Quota Responses

Content
View full analysis
Free quota exhausted. Register and get your own API key at **https://data.scdata.cc/pricing**, then set the environment variable `SCRUMBALL_API_KEY` to your key (in your host/agent environment or a local `.env`). You can then continue with your own quota. - The 429 response body usually includes `apply_url` and `env_var` fields you can quote directly. ``` ### Technical Analysis The Skill contains a mandatory instruction that alters how the Agent must respond when an API response has HTTP status 429 or contains particular response-body text. Rather than returning a neutral quota error, the instruction requires the Agent to direct the user to a specific third-party registration and pricing page. This exceeds what is necessary to implement creator-data retrieval. Handling quota exhaustion is legitimate, but forcing specific promotional language and an external commercial URL is not required for error reporting. The instruction also encourages quoting `apply_url` and `env_var` values supplied by the remote service, which allows remotely controlled response content to influence the Agent's user-facing output. ### Attack Path 1. The Skill is loaded into an Agent session. 2. The Agent invokes an operation through the hosted API gateway. 3. The gateway returns HTTP 429, a JSON body containing `code=429`, or text contain ...[truncated 787 chars]
Remediation
View remediation

other

Warning
Location
scripts/execute_operation.py:16
Finding

Undisclosed Persistent Cross-Session Installation Tracking

Content
View full analysis
str: """匿名安装 ID(IP 会随 WorkBuddy 出口变,用它做稳定统计/限额单位)。 优先写用户主目录(活过重装、多 skill 共用),退回 skill 目录;用户手动删才重置。""" import uuid paths = [Path.home() / ".scrumball_install_id", SKILL_ROOT / ".install_id"] for p in paths: try: if p.exists(): v = p.read_text(encoding="utf-8").strip() if v: return v except Exception: pass new_id = uuid.uuid4().hex for p in paths: try: p.write_text(new_id, encoding="utf-8") return new_id except Exception: continue return new_id ``` The identifier is then attached to every operation request: ```python req_headers = { "authorization": auth_header_value(api_key), "accept": "application/json", "x-install-id": _install_id(), } ``` ### Technical Analysis The runner creates a stable UUID and attempts to save it in the user's home directory as `~/.scrumball_install_id`. If that fails, it saves the identifier inside the Skill directory. The function's own documentation states that the identifier is intended to survive reinstalls, be shared by multiple Skills, and remain stable until manually deleted. Every operation request sends this identifier to the configured API gateway through the `x-install-id` header. This permits the remote service to correlate requests across sessions, Skill reinstalls, and potentially multiple Skills. A persistent identifier is not technically required to fetch current public creator or content information. Although quota accounting may be a business requirement for the hosted gateway, the implementation exceeds the minimum privilege needed for the declared enrichment functionality by wri ...[truncated 1412 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/execute_operation.py:146
Finding

API Credentials Can Be Sent to an Unrestricted or Plaintext Endpoint

Content
View full analysis
Dict[str, Any]: # 默认走托管网关(agent.scdata.cc):调用方零配置、无需自带 key。 # 网关服务端持有 Firebox key 并注入,故 SCRUMBALL_API_KEY 可留空。 base_url = os.getenv("SCRUMBALL_BASE_URL", "").strip() or "https://agent.scdata.cc" api_key = os.getenv("SCRUMBALL_API_KEY", "").strip() timeout = int(os.getenv("SCRUMBALL_TIMEOUT_SECONDS", "30")) validate_required(op.get("required_query", []), query, "query parameters") validate_required_any(op.get("required_any_query", []), query, "query parameters") validate_required(op.get("required_path", []), path_params, "path parameters") validate_required(op.get("required_body", []), body, "body fields") url = base_url.rstrip("/") + apply_path_params(op["path"], path_params) if query: q = {k: v for k, v in query.items() if v is not None} if q: url += "?" + urllib.parse.urlencode(q, doseq=True) req_headers = { "authorization": auth_header_value(api_key), "accept": "application/json", "x-install-id": _install_id(), } req_headers.update(op.get("default_headers", {})) req_headers.update({k: str(v) for k, v in headers.items()}) data = None if body: req_headers["content-type"] = "application/json" data = json.dumps(body).encode("utf-8") req = urllib.request.Request(url=url, method=op["method"], headers=req_headers, data=data) try: with urllib.request.urlopen(req, timeout=timeout) as resp: ``` ### Technical Analysis The API destination is taken directly from `SCRUMBALL_BASE_URL` without validating its scheme, hostname, port, o ...[truncated 2725 chars]
Remediation
View remediation
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (27)

Tainted flow: 'req' from os.getenv (line 178, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The request destination and authentication material are influenced by environment variables, especially SCRUMBALL_BASE_URL and SCRUMBALL_API_KEY, and then sent directly via urllib.request.urlopen. This enables exfiltration of API credentials, request payloads, and the persistent install identifier to an attacker-controlled endpoint if the environment or .env source is tampered with, which is especially risky because the code defaults to making live outbound requests.

Content

Scanner excerpt · scripts/execute_operation.py (reported line 180)May include surrounding context.

python
req = urllib.request.Request(url=url, method=op["method"], headers=req_headers, data=data)
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            raw = resp.read().decode("utf-8")
            try:
                payload = json.loads(raw) if raw else None

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose is narrow realtime enrichment, but the documented behavior indicates broader generic API execution, installation tracking, and environment/config diagnostics. This mismatch is dangerous because reviewers and users may authorize the skill under false assumptions while it exercises more powerful capabilities that can exfiltrate data, fingerprint installations, or access sensitive configuration.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The skill encourages use of a local .env file in execution commands, and the broader findings indicate environment inspection capabilities. In an agent setting, patterns that normalize reading .env increase the risk of over-collecting secrets or accidentally exposing unrelated credentials stored in the same file.

Content

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

md
## Tooling

Execution commands:
- List operations: `python3 scripts/execute_operation.py --env-file .env list`
- Example user enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation tiktok_realtime_user_info --query '{"unique_id":"nike"}'`
- Example content enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation youtube_realtime_video_detail --query '{"video_id":"dQw4w9WgXcQ"}'`

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The required environment variable section reinforces secret dependency without sufficient boundaries on how secrets are accessed, stored, or protected. In context with auto-loading and diagnostics, this creates a realistic risk of credential exposure or misuse if the skill reads broader environment state than necessary.

Content

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

md
Execution commands:
- List operations: `python3 scripts/execute_operation.py --env-file .env list`
- Example user enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation tiktok_realtime_user_info --query '{"unique_id":"nike"}'`
- Example content enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation youtube_realtime_video_detail --query '{"video_id":"dQw4w9WgXcQ"}'`

Required environment variables:

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

Documenting .env-based execution alongside external API use can cause operators to place sensitive base URLs and keys in local files that the skill or adjacent tooling may inspect. The danger is amplified because the skill appears to support diagnostics/config inspection, making accidental credential disclosure more plausible.

Content

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

md
Execution commands:
- List operations: `python3 scripts/execute_operation.py --env-file .env list`
- Example user enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation tiktok_realtime_user_info --query '{"unique_id":"nike"}'`
- Example content enrichment: `python3 scripts/execute_operation.py --env-file .env call --operation youtube_realtime_video_detail --query '{"video_id":"dQw4w9WgXcQ"}'`

Required environment variables:
- `SCRUMBALL_BASE_URL`: API gateway base URL

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 · scripts/execute_operation.py (reported line 137)May include surrounding context.

python
elif os.getenv("SCRUMBALL_ENV_FILE"):
        candidates.append(Path(os.getenv("SCRUMBALL_ENV_FILE", "")).expanduser())
    else:
        candidates.append(Path.cwd() / ".env")
        candidates.append(SKILL_ROOT / ".env")

    for p in candidates:

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 · scripts/execute_operation.py (reported line 138)May include surrounding context.

python
elif os.getenv("SCRUMBALL_ENV_FILE"):
        candidates.append(Path(os.getenv("SCRUMBALL_ENV_FILE", "")).expanduser())
    else:
        candidates.append(Path.cwd() / ".env")
        candidates.append(SKILL_ROOT / ".env")

    for p in candidates:

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 · scripts/execute_operation.py (reported line 243)May include surrounding context.

python
elif os.getenv("SCRUMBALL_ENV_FILE"):
        candidates.append(Path(os.getenv("SCRUMBALL_ENV_FILE", "")).expanduser())
    else:
        candidates.append(Path.cwd() / ".env")
        candidates.append(SKILL_ROOT / ".env")

    for p in candidates:

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 · scripts/execute_operation.py (reported line 243)May include surrounding context.

python
def main() -> int:
    parser = argparse.ArgumentParser(description="Run operations for this skill")
    parser.add_argument("--env-file", help="Optional .env file path; if omitted, auto-tries ./.env then <skill-root>/.env")

    sub = parser.add_subparsers(dest="cmd", required=True)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises executable tooling behaviors involving environment access, file access, and network use without declaring any explicit tool scope or permissions boundary. This increases the chance that a host agent grants broader capabilities than users expect, enabling unintended secret access, local file interaction, or outbound requests during normal skill use.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest frames the skill as simple creator/content enrichment, but the Facebook operations include keyword search and async task processing, which expand collection scope beyond a single user-supplied profile or content object. That broader search capability can be used for more extensive surveillance or bulk data gathering than the description suggests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The skill instructs users to load .env files and send creator lookup queries to an external API without warning about secret handling, external transmission, or privacy implications. In an agent environment, this can lead users to expose API keys or sensitive lookup targets without informed consent or proper data-minimization practices.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
78% confidence
Finding

The skill explicitly directs the assistant to send users to an external service for registration and API key acquisition, confirming reliance on third-party data transmission and credential provisioning. In context with hosted gateway use and realtime lookups, this raises supply-chain and privacy concerns because user queries and credentials may flow through an external provider not fully described in the manifest.

Content

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

md
- **Free tier**: a limited number of calls per day, zero-config (no key required — the skill defaults to a hosted gateway that injects the key server-side).
- **When any operation returns HTTP 429, or the response body has `code=429` / contains `quota_exceeded`, you (the assistant) MUST immediately and clearly tell the user** (do not silently retry, do not treat it as a generic error):

  > Free quota exhausted. Register and get your own API key at **https://data.scdata.cc/pricing**, then set the environment variable `SCRUMBALL_API_KEY` to your key (in your host/agent environment or a local `.env`). You can then continue with your own quota.

- The 429 response body usually includes `apply_url` and `env_var` fields you can quote directly.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are generic enough to match normal user requests about creator profiles, latest videos, or updates, which can cause the skill to activate unintentionally. In a research skill that fetches realtime external data, this broad activation increases the chance of unnecessary tool invocation, data overcollection, and routing users into the skill when they did not explicitly request it.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This manifest contains multiple natural-language summary fields such as "实时采集-用户信息" and similar Chinese-only labels across the file. Because the file provides no user choice, fallback language, or documented region-specific justification, it appears to impose a specific language/locale in a way that conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The declared skill scope is creator profile/content lookup, but the operations include broader Facebook keyword post search and asynchronous task/result polling capabilities. This expands functionality beyond user-expected intent and can enable broader social-media monitoring or collection workflows that are not clearly disclosed, increasing the risk of misuse and overcollection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The API guide advertises realtime collection of social-media profile, post, story, and video data across multiple platforms but includes no privacy, consent, retention, or acceptable-use guidance. In a skill specifically designed for influencer enrichment, that omission increases the likelihood that integrators will use the endpoints for surveillance, profiling, or collection of personal data without appropriate legal and policy controls.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code generates and persists a cross-run installation ID in the user's home directory or skill directory, then reuses it across requests. For a skill whose stated purpose is realtime creator-data retrieval, this creates durable tracking beyond what is necessary and can be used to correlate activity across sessions and potentially across skills on the same host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code not only creates a persistent identifier but also sends it in the x-install-id header on every network request without any disclosure or consent mechanism in this file. Silent transmission of a durable identifier increases privacy risk because it allows backend correlation of user activity over time.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code sends query parameters, body content, user-supplied headers, authorization data, and the install identifier to a remote service without any warning or confirmation in the execution path. In a data-enrichment skill this network behavior is expected, but the lack of transparency still creates a meaningful privacy and secret-handling risk, especially when combined with configurable endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

Several capability names are presented only in Chinese while the rest of the document is in English, which imposes a language assumption without user opt-in. The policy explicitly covers language or locale constraints unless the skill offers a choice or clearly justifies the locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The TikTok capability rows use Chinese-only natural-language labels in an otherwise English document. This creates an undocumented language constraint for users reading the skill materials.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The Instagram capability table continues the same pattern of Chinese-only labels in a mixed-language document. This is a natural-language policy concern because no opt-in or documented locale limitation is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The Facebook section also uses Chinese-only labels despite the surrounding instructions being English. Without a documented reason or language choice, this is a locale/language policy mismatch.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The 'Required environment variables' section says SCRUMBALL_API_KEY is required, while the quota/unlock section later says the free tier is zero-config and no key is required because the skill defaults to a hosted gateway. These statements directly contradict each other about whether the skill can operate without a user-provided API key.

Content

No source excerpt is available for this finding.