T09 · Insecure Skill Coding Practices
- Location
scripts/config.py:10- Finding
Environment-Controlled API Endpoint Can Expose Credentials and Sensitive Documents
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The vehicle-license OCR skill has a coherent purpose, but it stores an API key in plaintext and can send sensitive document data to a configurable external API, so it belongs in Review before installation.
Install only if you are comfortable sending vehicle-license images or base64 contents to the XiaoBenYang API and storing the service API key in a local .env file. Prefer a runtime secret store, pin dependencies, restrict or remove base_url overrides, and add a clear privacy notice before using it with real personal or vehicle-registration documents.
scripts/config.py:10Environment-Controlled API Endpoint Can Expose Credentials and Sensitive Documents
scripts/config.py:39API Key Is Persisted in a Plaintext File Without Permission Hardening
requirements.txt:1Unbounded Dependency Versions Make Builds Non-Reproducible
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.
The skill is presented as a vehicle-license OCR tool, but it also manages and persists API keys via .env and accesses environment/configuration state, behavior not disclosed in the user-facing purpose statement. Because the handled document contains highly sensitive personal and vehicle-registration data, hidden credential-management and storage behavior materially increases security and privacy risk.
The skill is presented as a vehicle-license OCR tool, but it also manages and persists API keys via .env and accesses environment/configuration state, behavior not disclosed in the user-facing purpose statement. Because the handled document contains highly sensitive personal and vehicle-registration data, hidden credential-management and storage behavior materially increases security and privacy risk.
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",
)
The code forcefully reads .env content and manually extracts XBY_APIKEY, bypassing normal configuration boundaries and increasing secret exposure within the application. In an OCR-only skill, custom secret parsing is unnecessary and makes credential access behavior more suspicious and harder to audit.
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")
Checking for and opening a local .env file to read credentials is a form of direct secret access that broadens the application's handling of sensitive data. This is especially questionable in a document OCR skill where secret file inspection is not part of the core function and can facilitate later misuse or exfiltration.
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
This function explicitly persists an API key into a .env file, creating durable credential storage on disk that may be readable by other processes, accidentally committed, or harvested later. Because the skill's stated purpose is OCR, this credential-storage capability is not well-justified and materially increases the danger of secret compromise.
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 exposes capabilities for environment access, file read/write, and network use, but does not declare any explicit permission or allowed-tool scope. This weakens least-privilege controls and makes it harder for reviewers and runtime policy to constrain sensitive operations such as API-key storage and outbound transmission.
The skill instructs sending vehicle registration images or base64-encoded document contents to an external OCR API, but it does not provide an explicit privacy notice, consent flow, retention policy, or warning about third-party data sharing. Because vehicle licenses contain highly sensitive personal information, undisclosed external transmission creates significant privacy, compliance, and misuse risk.
References to an unrelated 'gaokao' project/function example inside a vehicle-license OCR skill indicate copy-paste inconsistency and poor provenance control. Such inconsistency raises the chance of misrouted tool calls, reviewer confusion, and accidental invocation of unintended functionality, which is especially risky in a skill that handles sensitive documents and credentials.
This code performs an HTTP POST to an external endpoint and sends both caller-supplied parameters and an API key in headers. While it logs success and errors internally, there is no confirmation prompt or user-facing warning in the file explaining that user/system data may be transmitted off-box.
The OCR skill includes logic to persist and manage an API key in a local .env file, which is broader than what is necessary for simple document recognition and expands the credential-handling attack surface. Storing secrets on disk can expose them to other local users, accidental source control commits, backups, or unrelated components that can read the workspace.
The function writes API credentials directly to a local .env file without any access-control hardening or purpose limitation tied to OCR processing. In this skill context, local credential file write capability is unnecessary and increases the chance of secret leakage through filesystem exposure, repository inclusion, or later exfiltration by other code.
The code silently persists an API key to .env with no user-facing warning or confirmation, creating a risk that operators do not realize credentials are being stored on disk. Hidden persistence increases the likelihood of accidental disclosure via local inspection, backups, logs, or source control.
This function sends vehicle license image content or a URL to an external API for OCR, which involves highly sensitive personal and vehicle-identifying data. The file provides no visible consent flow, privacy notice, data-handling constraints, or safeguards around what endpoints may receive the data, so users may unknowingly transmit regulated personal information off-platform.
The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens reproducibility and can unintentionally pull in vulnerable or breaking releases of requests, especially relevant because this OCR skill likely handles sensitive vehicle document data and may make outbound API calls.
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
The manifest does not pin requests, and the package has multiple known advisories across versions, so the actual installed version may be affected without visibility. In an OCR integration, requests is likely used for network communication, making credential leakage, TLS handling flaws, or other client-side issues more consequential if a vulnerable release is resolved.
Using pydantic with only a minimum version means builds are not deterministic and may consume later versions with newly introduced vulnerabilities or incompatible behavior. Since this package is often involved in parsing untrusted input and configuration, version drift increases security and reliability risk.
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Because pydantic is not pinned, it is impossible to verify from this file whether deployment uses a version affected by known advisories such as denial-of-service issues. If the skill parses attacker-controlled OCR outputs, request bodies, or configuration, a vulnerable parser version could increase exposure to malformed-input attacks.
The unpinned pydantic-settings requirement permits uncontrolled version selection during installation. That can expose deployments to supply-chain instability or known package flaws if a later resolved release is vulnerable.
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
The dependency on pydantic-settings is unverifiable because no exact version is fixed, and at least one advisory exists for the package. Given that settings libraries often read secrets and filesystem paths, an affected version could have security implications if the application uses nested secrets or local secret mounts.
python-dotenv is also unpinned, so different environments may install different versions, including releases later found to contain security defects. For software that may process sensitive OCR-related credentials or API settings from .env files, this increases operational and security uncertainty.
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
python-dotenv has known advisories, but without an exact version the resolved package may still be vulnerable. Because dotenv tooling can read or modify environment files containing API keys and service credentials, flaws such as symlink-following could matter in certain deployment or local tooling scenarios.
The class docstring says '小笨羊高考Skill配置', which refers to a gaokao/exam-related skill rather than the manifest's vehicle license OCR skill. This active documentation mismatch suggests the file was repurposed without updating intent documentation, creating ambiguity about the skill's true purpose.