Back to skill

Security audit

出海匠 TikTok 达人情报

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed LinkFox creator-research client, but it also includes account login, API-key generation, billing order creation, redirectable authenticated endpoints, and unsafe local path handling that warrant Review before installation.

Install only if you trust LinkFox with your API key, session metadata, creator-query results, and any account/billing actions. Avoid setting custom LINKFOX_* endpoint variables unless you control and trust the destination, use a dedicated low-privilege API key when possible, do not paste keys into shared logs or synced dotfiles, and review any payment order before scanning or opening a QR code.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/chuhaijiang_creator_search.py:29
Finding

Redirectable API Endpoints Can Exfiltrate Authentication Credentials

Content
View full analysis
str: """Gateway base address: environment override, then production default.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def get_api_key(): key = (os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY")) if not key: sys.exit(1) return key def call_api(params): global _LAST_CALL_WAS_HTTP_ERROR _LAST_CALL_WAS_HTTP_ERROR = False api_url = get_api_url() api_key = get_api_key() data = json.dumps(params).encode("utf-8") headers = { "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.0", "SESSION_ID": (os.environ.get("SESSION_ID") or "").strip(), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), } req = Request(api_url, data=data, headers=headers, method="POST") try: with urlopen(req, timeout=150) as response: raw = response.read().decode("utf-8") try: return json.loads(raw) except json.JSONDecodeError: return {"error": "Invalid JSON response", "details": raw[:500]} except HTTPError as e: _LAST_CALL_WAS_HTTP_ERROR = True body = e.read().decode("utf-8", errors="replace") if e.fp else "" try: return json.loads(body) if body else { "error": f"HTTP { ...[truncated 2929 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/chuhaijiang_creator_search.py:156
Finding

Unnecessary Agent and Session Metadata Is Forwarded to the Gateway

Content
View full analysis
dict: url = f"{_agent_base()}{path}" body_bytes = json.dumps(body or {}).encode() if method == "POST" else None headers = { "Authorization": _api_key(), "SESSION_ID": (os.environ.get("SESSION_ID") or "").strip(), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), } if method == "POST": headers["Content-Type"] = "application/json" req = Request(url, method=method, data=body_bytes, headers=headers) with urlopen(req, timeout=30) as resp: return json.loads(resp.read().decode()) ``` ### Technical Analysis The creator endpoints require request parameters and an authorization credential. The reviewed code also for ...[truncated 1558 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/chuhaijiang_creator_search.py:38
Finding

Unsanitized SESSION_ID Enables Path Traversal and Arbitrary Writable-Path Output

Content
View full analysis
str: """Prefer SESSION_ID; otherwise generate a process-stable identifier.""" env = (os.environ.get("SESSION_ID") or "").strip() if env: return env if "_auto" not in _SESSION_CACHE: _SESSION_CACHE["_auto"] = ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) return _SESSION_CACHE["_auto"] def _ensure_session(ts: float) -> tuple[str, str]: date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _session_id(ts) root = _linkfox_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` The selected directory is subsequently used for persistent files: ```python def resolve_data_path(slug: str, ts: float, ext: str = "json") -> str: _, session_dir = _ensure_session(ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join( data_dir, f"{slug}-{int(ts * 1_000_000)}.{ext}", ) _update_meta( session_dir, skill=slug, file_rel=os.path.relpath(out, session_dir), ts=ts, ) return out ``` ```python out_path = _resolve_output_path(ts) with open(out_path, "w", encoding="utf-8") as f: f.write(serialized) ``` ### Technical Analysis `SESSION_ID` is accepted without validation and passed directly to `os.path.join`. An absolute value causes earlier path components to be discarded on applicable platforms. Relative values containing `..` can esca ...[truncated 1746 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:475
Finding

Onboarding Exposes Bearer API Keys Through Standard Output and Shell Startup Files

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: invalid phone format: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: invalid verification-code format: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{TAG} {lbt['error']}", file=sys.stderr) info = _fetch_user_info_v3(lg["access_token"], lg["user_id"]) if "error" in info: return {"error": info["error"], "phone": masked} tok = _get_or_generate_api_token( lg["access_token"], lg["user_id"], info["group_id"], ) if "error" in tok: return {"error": tok["error"], "phone": masked} return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) def _cmd_login(args) -> int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print(f"{TAG} API key obtained", file=sys.stderr) return 0 return 1 ``` The setup reference recomm ...[truncated 1823 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:38
Finding

Onboarding Recommends Unpinned Third-Party Dependency Installation

Content
View full analysis
dict: try: import qrcode except ImportError: return { "png_path": None, "ascii_qr": None, "error": "Missing qrcode dependency; install qrcode and pillow", } ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; install requests" ) ``` The original runtime messages instruct users to install `requests`, `qrcode`, and `pillow` without version or hash constraints. ### Technical Analysis The package names are common and no typosquatting or deliberately malicious package was identified. Nevertheless, installing dependencies by mutable name without a version lock or integrity hash makes the runtime non-reproducible. A future compromised release, malicious package-index response, dependency substitution, or incompatible update could execute code during installation or import. The Skill does not include a lockfile or hash-verified requirements manifest in the reviewed project. ### Attack Path 1. The user invokes an onboarding command on a system missing one of the optional packages. 2. The script instructs the user to install packages without version or hash restrictions. 3. The package installer resolves the currently available release from its configured index. 4. A compromised package release, compromised index, or maliciously configured package source supplies attacker-controlled code. 5. Installation hooks or subsequent imports execute that code with the user's operating-system privileges. ### Impact Assessment If the dependency supply chain is compromised, arbitrary co ...[truncated 408 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (45)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The script allows the destination base URL to be overridden by the LINKFOX_TOOL_GATEWAY environment variable and sends the API key plus session-related identifiers in request headers to that URL. If an attacker can influence the environment, they can redirect requests to an attacker-controlled endpoint and exfiltrate credentials and request data, making this a real SSRF/credential-leakage risk.

Content

Scanner excerpt · scripts/chuhaijiang_creator_rank_agencies.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The request sent to the gateway includes multiple HTTP headers populated directly from environment variables, including SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME, and the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY. Because these values are attacker-controllable in many execution environments, the script can be induced to exfiltrate workflow metadata and API credentials to an arbitrary endpoint or enable header abuse against the upstream service. In this skill context, the script is explicitly designed to call an external API with sensitive authorization, which makes environment-to-network taint especially dangerous.

Content

Scanner excerpt · scripts/chuhaijiang_creator_rank_commercial.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/chuhaijiang_creator_detail.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/chuhaijiang_creator_rank_growth.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/chuhaijiang_creator_related_lives.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The script copies multiple environment variables directly into outbound HTTP headers, including SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME, and also allows the destination base URL to be overridden via LINKFOX_TOOL_GATEWAY. In an agent or multi-tenant runtime where environment variables may be influenced by upstream context, this creates a tainted-data-to-network sink that can leak sensitive execution metadata or send it to an attacker-controlled endpoint, especially because the Authorization key is included on the same request.

Content

Scanner excerpt · scripts/chuhaijiang_creator_related_products.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request sent via urlopen includes multiple headers sourced directly from environment variables, and the destination base URL is also environment-controlled via LINKFOX_TOOL_GATEWAY. This creates a tainted-flow issue where untrusted runtime metadata and potentially sensitive identifiers are transmitted over the network, and if the gateway is overridden, the API key and session metadata could be exfiltrated to an attacker-controlled endpoint.

Content

Scanner excerpt · scripts/chuhaijiang_creator_related_videos.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The script forwards multiple environment-derived values into outbound HTTP headers and allows the base URL to be overridden by LINKFOX_TOOL_GATEWAY. In an agent environment where these variables may be influenced by other components, this can exfiltrate session identifiers, message metadata, and the API key to an attacker-controlled endpoint or unintended service.

Content

Scanner excerpt · scripts/chuhaijiang_creator_search.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'url' from os.environ.get (line 234, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The POST target is derived from environment-controlled base URLs, and this function sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens. In a skill execution environment, an attacker who can influence environment variables can redirect these requests to an attacker-controlled host and exfiltrate credentials or payment-related data.

Content

Scanner excerpt · scripts/onboarding.py (reported line 195)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

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

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The gateway request URL is built from environment-controlled base URLs and then invoked with Authorization and session headers via urlopen. If those environment variables are manipulated, API keys and account metadata can be sent to an attacker-controlled endpoint, enabling credential theft and abuse of billing or account operations.

Content

Scanner excerpt · scripts/onboarding.py (reported line 247)May include surrounding context.

python
headers["Content-Type"] = "application/json"
    req = Request(url, method=method, data=body_bytes, headers=headers)
    try:
        with urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        status = e.code

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

If the broader skill package actually includes SMS login, token handling, API-key generation, account/team inspection, subscription listing, order creation, QR-code payment generation, and payment-status queries while presenting itself as a public TikTok market research skill, that is a serious description-behavior mismatch. Undisclosed authentication and payment operations materially increase the attack surface and could enable account abuse, token exposure, or unauthorized billing workflows under misleading pretenses.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the broader skill package actually includes SMS login, token handling, API-key generation, account/team inspection, subscription listing, order creation, QR-code payment generation, and payment-status queries while presenting itself as a public TikTok market research skill, that is a serious description-behavior mismatch. Undisclosed authentication and payment operations materially increase the attack surface and could enable account abuse, token exposure, or unauthorized billing workflows under misleading pretenses.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the broader skill package actually includes SMS login, token handling, API-key generation, account/team inspection, subscription listing, order creation, QR-code payment generation, and payment-status queries while presenting itself as a public TikTok market research skill, that is a serious description-behavior mismatch. Undisclosed authentication and payment operations materially increase the attack surface and could enable account abuse, token exposure, or unauthorized billing workflows under misleading pretenses.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Response fields vary by endpoint and optional detail expansion. Read `references/api.md` before parsing nested fields and preserve the runtime types returned by

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Response fields vary by endpoint and optional detail expansion. Read `references/api.md` before parsing nested fields and preserve the runtime types returned by

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Response fields vary by endpoint and optional detail expansion. Read `references/api.md` before parsing nested fields and preserve the runtime types returned by

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Response fields vary by endpoint and optional detail expansion. Read `references/api.md` before parsing nested fields and preserve the runtime types returned by

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

python scripts/chuhaijiang_creator_rank_growth.py '{"country":"us","date":"20260828","granularity":"daily","pageSize":5}'

text

## Display Rules

1. State the marketplace, filters, ranking window, total count, and current page when available.
2. For creator lists, show identity, audience size, engagement, content volume, commerce metrics, category, and creator ID when returned.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/onboarding.md (reported line 14)May include surrounding context.

md
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `api_key` 后把下面三平台配置转发给用户,提示重启会话生效:
     - Windows PowerShell(永久):`setx LINKFOX_AGENT_API_KEY "<key>"`
     - macOS zsh:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
     - Linux bash:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`
     - 变量名 `LINKFOX_AGENT_API_KEY`(主推)或 `LINKFOXAGENT_API_KEY`(老规范)任一即可

**billing 场景**:`errcode=402` 或消息含 `算力/余额/quota/insufficient/充值/套餐到期`。
- `python scripts/onboarding.py list-plans` → 有 AskUserQuestion 就弹菜单,否则输出编号清单让用户选
- 校验 `plan_id` ∈ 清单、支付方式 ∈ 该套餐 `available_methods`(通常 `wechat/alipay`)
- `python scripts/onboarding.py order <plan_id> <method>` → 展示优先级 PNG

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements SMS login, API-key retrieval, subscription listing, order creation, and payment QR generation, which are materially unrelated to a TikTok creator-research skill. That scope mismatch is dangerous because it introduces account, credential, and billing capabilities into a data-analysis skill, expanding the blast radius far beyond the declared purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill can create orders and render payment QR codes, which enables real billing actions not justified by the stated research use case. In the context of an agent skill, this is especially risky because a compromised or misleading invocation could trigger unauthorized purchases or social-engineer a user into paying.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs use of environment variables, networked API calls, and mandatory local file writes, but it does not declare any explicit tool scope such as allowed tools or permissions. That gap weakens security boundaries because reviewers and runtime policy layers cannot clearly enforce or audit what the skill is allowed to access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file presents core usage and safety-relevant operating instructions in Chinese only for sections such as invocation, output behavior, and authentication/quota handling, while other sections are in English. This imposes a language constraint without explicit user opt-in or a documented locale-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

该 markdown 文档标题及整体说明均以中文撰写,没有说明这是仅面向中文用户或特定区域的限定文档,也未提供其他语言选择。根据策略,若技能在自然语言层面强制特定语言而无用户选择或明确正当性,应视为语言/locale 策略风险。

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api.md (reported line 271)May include surrounding context.

md
| 501 | 参数校验失败 | 根据 `errmsg` 修正参数 |
| 其他非 200 | 业务异常 | 回显错误信息,不自动连续重试付费接口 |

## curl 示例

### 达人搜索