T01 · Skill Instruction Hijacking
- Location
SKILL.md:222- Finding
Unconditional Agent Identity and Channel Override
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill’s core LinkFox compliance API use is coherent, but it has review-worthy risks around credential-bearing requests, mutable remote installation instructions, host-identity attribution, and local persistence of sensitive results.
Install only if you trust LinkFox and are comfortable sending product images, descriptions, patent queries, phone/SMS login data, and API credentials to its services. Do not set custom LINKFOX_TOOL_GATEWAY or related endpoint variables unless you control and trust the destination. Avoid following the remote release.zip install fallback without a pinned version and checksum, and keep the linkfox output/cache directory out of shared workspaces because it stores full responses.
SKILL.md:222Unconditional Agent Identity and Channel Override
references/linkfox-ruiguan-copyright-detection.md:122Remote Skill Package Installation Without Integrity Verification
scripts/onboarding.py:68Configurable Network Destinations Receive Authentication Secrets Without Validation
scripts/zhihuiya_cited_references.py:250Path Traversal Through Unsanitized Session Identifier
scripts/zhihuiya_cited_references.py:95Sensitive API Responses Persisted Without Restrictive Permissions or Cleanup
scripts/onboarding.py:162Unpinned Runtime Dependency Installation Instructions
The script builds request destinations from environment-controlled base URLs and then sends sensitive material to them, including phone numbers, SMS codes, access tokens, refresh tokens, and API keys during login and token-generation flows. If an attacker can influence environment variables such as LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL, the CLI can be redirected to an attacker-controlled server, causing credential exfiltration and full account/API-key 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 uses a URL derived from environment-controlled configuration and attaches the Authorization header from LINKFOX_AGENT_API_KEY before calling urlopen. An attacker who can set LINKFOX_AGENT_API_URL or related fallback variables can redirect these authenticated requests to an arbitrary endpoint and capture the API key or induce privileged actions against a rogue 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 via urlopen includes environment-derived values in headers, and the destination host is also overrideable through LINKFOX_TOOL_GATEWAY. This creates a real exfiltration path: a user or prior tool can point the script at an arbitrary server and cause SESSION_ID, MODE_ID, APP_NAME, the API key, and request payload data to be transmitted externally.
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 request includes multiple headers sourced directly from environment variables, and the destination base URL is also overridable via LINKFOX_TOOL_GATEWAY. In an agent/runtime context, attacker-controlled environment variables can redirect requests and exfiltrate sensitive API keys and session metadata to an arbitrary endpoint, making this a real SSRF/credential-leak style 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 request sent to urlopen includes environment-derived values in headers, and the destination host is also configurable via LINKFOX_TOOL_GATEWAY. This means secrets and identifiers such as the API key, SESSION_ID, MODE_ID, and APP_NAME can be exfiltrated to an attacker-controlled endpoint if the environment is manipulated, which is especially risky in agent/runtime environments where environment variables may be influenced externally.
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 request sent to urlopen includes headers derived 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 externally influenced, so this can exfiltrate API credentials and session metadata to an attacker-controlled endpoint via SSRF-style redirection.
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 ""
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
)
try:
with urlopen(req, timeout=150) as response:
result = json.loads(response.read().decode("utf-8"))
except HTTPError as e:
body = e.read().decode("utf-8") if e.fp else ""
The code uploads the entire local file to a presigned_url returned by a prior network call, without validating the destination host or scheme. If the gateway is compromised or LINKFOX_TOOL_GATEWAY is redirected to an attacker-controlled service, it can return a malicious upload URL and cause exfiltration of arbitrary local image files to an untrusted endpoint.
)
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 request sent to the network includes multiple headers populated directly from environment variables, and the destination base URL is also overridable via LINKFOX_TOOL_GATEWAY. In this skill context, that means secrets and session metadata can be exfiltrated to an attacker-controlled endpoint if the environment is influenced by untrusted input or a compromised runtime, making this a real SSRF/credential-leak style 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 request headers include multiple environment-derived values, and the destination base URL is also environment-controlled via LINKFOX_TOOL_GATEWAY. This creates a real exfiltration/SSRF-style risk in agent environments: secrets and session metadata can be transmitted to an attacker-controlled endpoint simply by setting environment variables, which is especially dangerous because the Authorization API key is always sent.
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 request sent via urlopen includes multiple headers sourced directly from environment variables, and the destination host is also overridable via LINKFOX_TOOL_GATEWAY. In an agent/runtime context where environment variables may be influenced by upstream orchestration or untrusted skill execution context, this can exfiltrate API credentials and session metadata to an attacker-controlled endpoint, making the tainted network flow a real SSRF/data-exfiltration 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 request sent to the network includes header values taken directly from environment variables, and the destination host is also overridable via LINKFOX_TOOL_GATEWAY. In an agent/runtime setting, environment variables are part of the trust boundary, so this permits exfiltration of sensitive session metadata and the API key to an attacker-controlled endpoint if the gateway variable is poisoned.
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 request URL is derived from an environment-controlled base URL via LINKFOX_TOOL_GATEWAY, and the code sends the API key in the Authorization header to whatever host that variable points to. In an agent/runtime context where environment variables may be influenced by untrusted configuration, this can cause SSRF-like outbound requests and credential exfiltration to an attacker-controlled endpoint.
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 request headers include values taken directly from environment variables, and the destination URL is also overrideable via LINKFOX_TOOL_GATEWAY. This allows a caller or surrounding runtime to redirect authenticated requests, including the API key and session metadata, to an attacker-controlled endpoint, creating a credential exfiltration/SSRF-style risk in an agent context where environment variables may be attacker-influenced.
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 request destination is influenced by the LINKFOX_TOOL_GATEWAY environment variable, so anyone who can control the execution environment can redirect API traffic to an attacker-controlled host. Because the request includes the Authorization API key and session metadata headers, this creates a credential exfiltration and data leakage path rather than a harmless configuration option.
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 ""
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 ""
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 ""
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 ""
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 ""
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 ""
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 ""
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 ""
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 ""
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 request includes multiple headers populated directly from environment variables, and the destination host is also overridable via LINKFOX_TOOL_GATEWAY. This allows untrusted runtime configuration to influence outbound network traffic and potentially exfiltrate sensitive identifiers or the API key to an attacker-controlled endpoint, especially in agent or CI environments where env vars may be externally set.
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 ""