T01 · Skill Instruction Hijacking
- Location
skills/linkfox-ruiguan-copyright-detection/SKILL.md:132- Finding
Silent Transmission of User Feedback and Intent to an External Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent LinkFox IP-risk workflow, but it includes silent feedback reporting plus credential, endpoint, and persistence patterns users should review before installing.
Install only if you trust LinkFox with the product images, prompts, detection inputs, feedback content, account tokens, and billing-related operations involved. Do not use unreviewed LINKFOX_* endpoint overrides, avoid saving API keys in shell startup files, and treat generated HTML reports as untrusted unless sanitized. Review the automatic feedback behavior carefully because it can send user statements or inferred intent to LinkFox without an explicit prompt at the time of submission.
skills/linkfox-ruiguan-copyright-detection/SKILL.md:132Silent Transmission of User Feedback and Intent to an External Service
skills/linkfox-aigc-textgen/scripts/aigc_textgen.py:323Credential-Bearing Requests Can Be Redirected to Arbitrary Environment-Controlled Hosts
skills/linkfox-report-generator/scripts/inject_report.py:157Generated Reports Allow Unsanitized HTML and JavaScript Injection
skills/linkfox-ruiguan-copyright-detection/scripts/ruiguan_copyright_detection.py:250Unsanitized SESSION_ID Permits Output-Path Traversal
skills/linkfox-aigc-textgen/references/onboarding.md:11Onboarding Documentation Encourages Plaintext Persistence of Bearer API Keys
skills/linkfox-aigc-textgen/scripts/onboarding.py:162Runtime Installation Instructions Use Unpinned Third-Party Dependencies
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
req = _lf_Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
try:
with _lf_urlopen(req, timeout=timeout) as resp:
if guessed_ext == "bin":
ct = resp.headers.get("Content-Type", "")
if "mp4" in ct:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
req = Request(url, data=data, headers=headers, method="POST")
try:
with urlopen(req, timeout=HTTP_TIMEOUT) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The POST target is derived from environment-controlled base URLs and is used for login and token-related requests that carry phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys. If an attacker can influence environment variables, the script can be redirected to an attacker-controlled endpoint, causing credential exfiltration and account compromise.
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 = ""
The gateway request URL is also built from environment-controlled configuration and is invoked with the Authorization header containing the API key. A manipulated environment can redirect authenticated requests to an attacker-controlled server, exposing secrets and enabling fraudulent account, package, or order operations.
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
download_media accepts an arbitrary caller-supplied URL and fetches it over the network with only a scheme check. This creates an SSRF-style primitive that can be abused to make outbound requests to attacker-chosen hosts, including internal or link-local services in environments with network access, and then store the retrieved content locally.
req = Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
try:
with urlopen(req, timeout=timeout) as resp:
# 从 Content-Type 进一步修正扩展名
if guessed_ext == "bin":
ct = resp.headers.get("Content-Type", "")
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
headers={"Content-Type": "application/json", "Authorization": api_token},
)
try:
with urlopen(req, timeout=30) as resp:
body = json.loads(resp.read().decode())
break
except urllib.error.HTTPError as e:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
headers={"Content-Type": "application/json", "Authorization": api_token},
)
try:
with urlopen(req, timeout=30) as resp:
body = json.loads(resp.read().decode())
break
except urllib.error.HTTPError as e:
The download_media function performs arbitrary outbound HTTP/HTTPS fetches on a caller-supplied URL with no allowlist, host validation, or private-address blocking. In an agent environment this creates an SSRF primitive that can be used to probe internal services, access metadata endpoints, or retrieve untrusted content into persistent session storage.
req = Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
try:
with urlopen(req, timeout=timeout) as resp:
# 从 Content-Type 进一步修正扩展名
if guessed_ext == "bin":
ct = resp.headers.get("Content-Type", "")
The code builds request destinations from environment-controlled base URLs and then sends sensitive data, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, to those endpoints. If an attacker can influence environment variables in the agent runtime, they can redirect authentication traffic and credentials to attacker-controlled infrastructure, creating an SSRF-style credential exfiltration path.
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 = ""
The gateway URL is derived from environment variables and used in urllib requests with the Authorization header populated from the API key. An attacker who can set the base URL can force the CLI to transmit bearer credentials and account/order data to an arbitrary server, compromising the user's account and enabling misuse of paid resources.
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
The request sent by urlopen includes multiple headers derived directly from environment variables, most importantly LINKFOX_TOOL_GATEWAY for the destination and Authorization/SESSION metadata headers. In an agent or multi-tenant execution environment, attacker-controlled environment variables can redirect requests to an arbitrary host and exfiltrate API keys and session metadata, making this a real SSRF-plus-secret-leak issue rather than a harmless configuration pattern.
method="POST",
)
try:
with urlopen(req, timeout=150) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The script allows API base URLs to be overridden via environment variables and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those URLs via requests.post. In a skill execution environment, a malicious wrapper or compromised runtime could redirect these requests to an attacker-controlled endpoint, causing credential exfiltration. The danger is amplified because this file performs authentication and token provisioning unrelated to the declared advisory purpose.
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 = ""
The gateway request path uses a URL derived from environment variables and attaches the Authorization header containing the API key before calling urlopen. An attacker who can influence the environment can redirect traffic and capture API credentials or manipulate downstream purchase/order operations. Because this skill also supports plan listing, order creation, and payment state queries, the redirected traffic could expose both credentials and billing metadata.
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
The request forwards multiple environment-derived values, including a caller-controlled gateway base URL and session metadata headers, directly into an outbound HTTP request. If an attacker can influence environment variables in the agent runtime, they can redirect requests to an arbitrary host and exfiltrate the API key and request payload, making this effectively an SSRF-plus-secret-leak issue.
method="POST",
)
try:
with urlopen(req, timeout=150) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The upload destination is taken from the presigned URL returned by the gateway and the code uploads the entire local file to that URL without validating the hostname, scheme, or expected storage provider. If the gateway is misconfigured, compromised, or pointed at an attacker-controlled base URL, local image contents can be exfiltrated to an unintended remote service.
)
try:
with urlopen(req, timeout=120) as response:
if response.status not in (200, 201):
print(f"Upload failed with status: {response.status}", file=sys.stderr)
sys.exit(1)
The script builds request destinations from environment-controlled base URLs and then sends sensitive data to them via requests.post. Because this file handles phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, a tampered environment can silently redirect those secrets to an attacker-controlled endpoint, causing credential exfiltration and account compromise.
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 = ""
The gateway request path uses urllib with a URL derived from environment variables and attaches the API key in the Authorization header. If the runtime environment is influenced by a malicious actor, outbound requests can be redirected to an arbitrary host, leaking the API key and enabling unauthorized use of the victim's account and billing resources.
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
The script builds outbound request headers from environment variables including SESSION_ID, MESSAGE_ID, MODE_ID, APP_NAME, and the API key, then sends them to a remote endpoint whose base URL is itself overrideable via LINKFOX_TOOL_GATEWAY. This creates a real exfiltration and SSRF-style risk: a compromised runtime or untrusted environment can redirect requests and leak credentials and session metadata to an attacker-controlled host.
method="POST",
)
try:
with urlopen(req, timeout=150) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The script allows network destinations to be derived from environment variables and then sends sensitive authentication material, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, to those endpoints. In a hostile or multi-tenant runtime, an attacker who can influence environment variables can redirect requests to attacker-controlled infrastructure and harvest credentials.
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 = ""
The gateway request path uses a URL assembled from environment-controlled base configuration and then performs authenticated requests with the API key in the Authorization header. If the environment is manipulated, the skill can be coerced into exfiltrating the API key and order/account data to an attacker-controlled server.
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
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
method="POST",
)
try:
with urlopen(req, timeout=150) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The code builds request destinations from environment-controlled base URLs and then sends sensitive login/API-key traffic with requests.post. In this script, those flows include SMS login, access tokens, refresh tokens, and generated API keys, so an attacker who can influence environment variables can redirect secrets to an attacker-controlled endpoint.
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 = ""
The gateway URL is derived from environment variables and then used in urllib.request.urlopen with the Authorization header carrying the agent API key. If an attacker can set LINKFOX_AGENT_API_URL or related variables, they can exfiltrate credentials and manipulate order/account responses by acting as the remote service.
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
The request sent to the remote gateway includes multiple headers populated directly from environment variables, and the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY. In an agent/runtime context, environment variables are often influenced by orchestration or untrusted execution context, so this creates a tainted outbound network flow that can exfiltrate session metadata and API credentials to an attacker-controlled endpoint if the base URL is redirected.
method="POST",
)
try:
with urlopen(req, timeout=150) as response:
return json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The code builds request destinations from environment variables such as LINKFOX_LOGIN_API_URL and LINKFOX_AGENT_USER_API_URL, then sends authentication data, SMS-login payloads, access tokens, refresh tokens, and API-token requests to those URLs with requests.post. If an attacker can influence the process environment, they can redirect these secrets to attacker-controlled infrastructure, turning this into credential exfiltration and SSRF-style outbound communication.
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 = ""
No suspicious patterns detected.