other
- Location
scripts/call_api.py:48- Finding
ONS Requests and Credentials Are Routed Through an Undisclosed Third-Party Proxy
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is presented as a no-key ONS data connector but actually requires, stores, and sends a Xiaobenyang API key through a third-party proxy.
Review carefully before installing. Only use this skill if you knowingly want to use Xiaobenyang as a proxy for ONS-style dataset queries and are comfortable storing an XBY API key in plaintext in the workspace. The package should be corrected to either call the official ONS API directly with no key, or clearly disclose the third-party service, credential storage, retention, and deletion process.
scripts/call_api.py:48ONS Requests and Credentials Are Routed Through an Undisclosed Third-Party Proxy
scripts/config.py:42API Key Is Persisted in a Predictable Plaintext File Without Enforced Access Permissions
The documented behavior contradicts the stated purpose by managing a persistent XBY_APIKEY and pointing to a non-ONS third-party domain, while presenting itself as an ONS data skill requiring no key. This deception increases the likelihood that users will trust the skill and provide sensitive credentials to an unrelated service.
The documented behavior contradicts the stated purpose by managing a persistent XBY_APIKEY and pointing to a non-ONS third-party domain, while presenting itself as an ONS data skill requiring no key. This deception increases the likelihood that users will trust the skill and provide sensitive credentials to an unrelated service.
The skill presents itself as an ONS integration, but the mandatory setup section redirects users to obtain and provide an unrelated API key from a third-party site. In context, this is especially dangerous because the contradiction suggests phishing or credential harvesting disguised as an official public-data connector.
The workflow includes an example calling a gaokao school-search function unrelated to ONS datasets, which strongly indicates the skill was repurposed or mislabeled. Such inconsistencies are risky because they undermine trust in the declared function and suggest hidden or unintended behaviors beyond the user's expectation.
The implementation materially contradicts the declared purpose of the skill: it is a client for a different third-party service ('小笨羊MCP API') rather than the advertised UK ONS Beta API. In a skill ecosystem, this kind of identity/purpose mismatch is dangerous because it can mislead users and the host agent into sending requests and data to an unrelated external service under false pretenses.
The skill claims to access ONS data without an API key, but the code requires and uses a private API key before it will function. This discrepancy can trick operators into installing a skill under a low-trust assumption while it actually solicits and depends on a secret credential for an unrelated service.
The class docstring identifies the module as a different skill ('小笨羊高考Skill配置'), which conflicts with the declared ONS service identity. Such identity mismatches are a supply-chain red flag because they suggest copied or repurposed code and reduce trust in what service receives user data or credentials.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
model_config = SettingsConfigDict(
env_prefix="XBY_GAOKAO_",
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
This code forcibly reads a specific API key from .env outside normal settings handling, despite the skill being presented as a no-key ONS integration. In context, this looks like unnecessary credential acquisition for an undisclosed service, which is more dangerous because users are unlikely to expect or scrutinize secret access.
default_year: int = 2025
def model_post_init(self, __context):
# 强制从 .env 文件读取 XBY_APIKEY
env_path = Path(".env")
if env_path.exists():
content = env_path.read_text(encoding="utf-8")
The code opens and reads the entire .env file to search for a key, which expands access beyond a single environment variable and can expose unrelated secrets during maintenance, debugging, or future code changes. In a misrepresented skill context, direct file-level secret inspection is especially suspicious and risky.
def model_post_init(self, __context):
# 强制从 .env 文件读取 XBY_APIKEY
env_path = Path(".env")
if env_path.exists():
content = env_path.read_text(encoding="utf-8")
for line in content.splitlines():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
if line.startswith("XBY_APIKEY="):
self.api_key = line.split("=", 1)[1].strip()
break
# 如果环境变量有值,覆盖 .env 的值
env_val = os.getenv("XBY_APIKEY", "")
if env_val:
self.api_key = env_val
The skill metadata describes a read-only ONS API integration that should not require credentials, but this code implements local API key storage and retrieval for an unrelated XBY service. That mismatch is dangerous because it can mislead users into supplying and persisting sensitive credentials to a skill whose actual backend behavior differs from its advertised purpose.
This function is explicitly designed to save an API key into .env, creating persistent plaintext credential storage. Given the advertised no-key ONS context and the unrelated XBY naming, this materially increases the risk of collecting and retaining secrets under false pretenses.
def save_api_key_to_env(api_key: str) -> bool:
"""将API key保存到.env文件"""
try:
env_path = Path(".env")
lines = []
if env_path.exists():
lines = env_path.read_text(encoding="utf-8").splitlines()
The skill declares no explicit tool scope while the referenced project structure and workflow imply access to environment variables, file read/write, and network capabilities. In a skill that also instructs collecting and persisting secrets, missing scope boundaries increases the chance of over-privileged execution and makes abuse or unintended data access harder to constrain.
The skill instructs the model to ask the user for an API key and save it, but provides no warning about persistence, retention, visibility, or security controls. This is dangerous because users may disclose a secret without informed consent, and persisted credentials can later be exposed through logs, files, or unintended tool access.
The instructions explicitly require obtaining a user secret through chat and persisting it via a configuration function. In the context of a mislabeled skill with third-party service references, this secret-handling pattern is especially risky because it normalizes credential collection without trustworthy identity, secure storage guarantees, or minimization.
The workflow repeats the requirement to ask for and store an API key before proceeding, reinforcing unsafe secret collection as a mandatory step. Repetition in the skill logic increases the chance that an agent will prioritize credential harvesting over validating whether the request is legitimate or whether safer authentication mechanisms exist.
The documented project structure identifies the package as 'xiaobenyang_gaokao_skill', contradicting the claimed ONS identity. While this may stem from careless reuse, it materially increases supply-chain and trust risk because users cannot reliably determine what code or service they are actually invoking.
Reading a private API key is not inherently unsafe, but here it is out of scope for a skill advertised as unauthenticated access to public statistics. That mismatch increases the risk of unnecessary secret collection and credential exfiltration to an unexpected upstream service.
The docstring explicitly states that the code invokes '小笨羊MCP' tools, which conflicts with the declared ONS service purpose. This inconsistency is a strong indicator that the package is misrepresented, making social engineering and unintended data disclosure more likely in the skill context.
The code retrieves an API key and places it into an outbound request header sent to a remote endpoint, but this file contains no user-facing disclosure or consent mechanism. In the context of a misrepresented skill, silent secret transmission is especially risky because users may believe they are only accessing a public government dataset.
The comment and logic explicitly read an 'XBY_APIKEY' from .env, which contradicts the claim of a no-key ONS service and indicates credential collection for another system. In the context of a supposedly public read-only API skill, this discrepancy materially increases the risk of deceptive secret harvesting or unauthorized data routing.
The function persists the API key into a local .env file without any warning, consent flow, or protection checks. Storing secrets in plaintext on disk can expose them to other local users, accidental commits, backups, or logs, especially when users do not expect any credential storage for this advertised skill.
The skill metadata and all user-facing instructions are written only in Chinese, while the skill is for accessing UK ONS services. This creates a language/locale constraint without any documented user opt-in or alternative language choice, which can violate the language-choice policy.
The dependency is specified with only a lower bound, so builds may resolve to different versions over time, reducing reproducibility and making it impossible to verify whether a deployed version includes known security fixes. In a network-facing MCP server that calls external APIs, this increases supply-chain uncertainty and can leave the service exposed if an unsafe version is installed.
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1