T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:96- Finding
Symlink Validation Bypass Allows Arbitrary Local File Upload
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This bank-check OCR skill is purpose-aligned, but it needs Review because sensitive financial images and credentials can be sent to a configurable remote endpoint and input validation can be bypassed with symlinks.
Install only if you are comfortable sending bank-check images to SCNet or the configured OCR endpoint. Keep SCNET_API_BASE at the official HTTPS SCNet URL, do not process symlinked files, and avoid uploading checks unless you have authorization from the account holder or signer.
scripts/main.py:96Symlink Validation Bypass Allows Arbitrary Local File Upload
scripts/main.py:120Unrestricted OCR Endpoint Can Receive Sensitive Documents and API Credentials
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# 获取技能根目录(脚本所在目录的上一级)
SKILL_ROOT = Path(__file__).parent.parent.absolute()
ENV_FILE = SKILL_ROOT / "config" / ".env"
# 支持的识别类型(白名单),防止技能被滥用于通用 OCR 上传
SUPPORTED_OCR_TYPES = {"BANK_CHECK"}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- read: local image files provided by the user
- execute: python3 subprocess to run scripts/main.py
- network: transmit the provided image to the configured SCNET_API_BASE (default https://api.scnet.cn/api/llm/v1)
- env: read SCNET_API_KEY and SCNET_API_BASE from the process environment or config/.env
homepage: https://github.com/SCNet-sugon/bank_check_ocr.git
dependencies:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- read: local image files provided by the user
- execute: python3 subprocess to run scripts/main.py
- network: transmit the provided image to the configured SCNET_API_BASE (default https://api.scnet.cn/api/llm/v1)
- env: read SCNET_API_KEY and SCNET_API_BASE from the process environment or config/.env
homepage: https://github.com/SCNet-sugon/bank_check_ocr.git
dependencies:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- read: local image files provided by the user
- execute: python3 subprocess to run scripts/main.py
- network: transmit the provided image to the configured SCNET_API_BASE (default https://api.scnet.cn/api/llm/v1)
- env: read SCNET_API_KEY and SCNET_API_BASE from the process environment or config/.env
homepage: https://github.com/SCNet-sugon/bank_check_ocr.git
dependencies:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- read: local image files provided by the user
- execute: python3 subprocess to run scripts/main.py
- network: transmit the provided image to the configured SCNET_API_BASE (default https://api.scnet.cn/api/llm/v1)
- env: read SCNET_API_KEY and SCNET_API_BASE from the process environment or config/.env
homepage: https://github.com/SCNet-sugon/bank_check_ocr.git
dependencies:
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
* [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
* [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
The skill explicitly performs sensitive actions—reading local files, invoking a Python subprocess, making outbound network requests, and accessing credentials—but does not declare a formal tool scope such as permissions or allowed-tools. This creates a governance gap where the runtime may permit broader execution than users or platform policy expect, increasing the risk of unintended file access, exfiltration of sensitive check images, or shell misuse.
The natural-language content of the skill, including the title, instructions, warnings, and example user invocations, is entirely in Chinese and does not indicate that other languages are supported or that the user is opting into Chinese output. This can violate language/locale policy because it implicitly constrains interaction language without an explicit user choice or a clearly documented, justified regional limitation.
The skill sends bank check images—containing highly sensitive financial data such as account numbers, amounts, signatures, and seals—to a third-party service over the network. Even though this behavior is disclosed, it is still a real data-exposure risk because compromise, misconfiguration, weak vendor controls, or user misunderstanding could lead to leakage of financial information and fraud.
- **读取本地文件**:仅读取用户作为 `filePath` 参数显式提供的本地图片文件。
- **执行子进程**:调用 `python3 scripts/main.py` 脚本完成识别流程。
- **网络传输**:将用户提供的支票图片以 `multipart/form-data` 形式上传至 `SCNET_API_BASE` 所配置的 OCR 接口(默认 `https://api.scnet.cn/api/llm/v1/ocr/recognize`)。
- **读取凭据**:从进程环境变量或 `config/.env` 中读取 `SCNET_API_KEY` 和 `SCNET_API_BASE`。
---
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SCNET_API_KEY=your_scnet_api_key_here
SCNET_API_BASE=https://api.scnet.cn/api/llm/v1
2. 添加:`SCNET_API_KEY=你的密钥`
3. 设置文件权限为 600(仅所有者可读写)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SCNET_API_KEY=your_scnet_api_key_here
SCNET_API_BASE=https://api.scnet.cn/api/llm/v1
2. 添加:`SCNET_API_KEY=你的密钥`
3. 设置文件权限为 600(仅所有者可读写)
The file explicitly routes uploaded documents to an external endpoint, which means bank checks and other sensitive OCR inputs leave the local trust boundary. External transmission is not inherently malicious, but in this skill's context it is security-relevant because the transmitted content can include account numbers, names, signatures, dates, and stamps without any accompanying disclosure or trust-boundary warning.
# Sugon-Scnet OCR API 文档摘要
## 接口地址
`POST https://api.scnet.cn/api/llm/v1/ocr/recognize`
## 请求头
- `Content-Type: multipart/form-data`
The document describes uploading potentially highly sensitive check and identity-related images to a third-party OCR API and even shows personal-data fields in example responses, but it provides no privacy, retention, consent, or data-handling guidance. In the context of a bank-check OCR skill, this is more dangerous because users may submit financial instruments and PII, creating a real risk of unauthorized disclosure, compliance violations, or improper downstream handling.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
" b) 配置文件:\n"
f" mkdir -p {SKILL_ROOT}/config\n"
f" echo 'SCNET_API_KEY=你的密钥' > {ENV_FILE}\n"
f" chmod 600 {ENV_FILE}\n"
"\n配置完成后重新运行。"
)
sys.exit(error_msg)
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
" b) 配置文件:\n"
f" mkdir -p {SKILL_ROOT}/config\n"
f" echo 'SCNET_API_KEY=你的密钥' > {ENV_FILE}\n"
f" chmod 600 {ENV_FILE}\n"
"\n配置完成后重新运行。"
)
sys.exit(error_msg)
The script uploads a user-supplied local file to an external OCR API at api.scnet.cn. This is a real data-exfiltration boundary: even though the skill is intended for bank checks, those documents commonly contain highly sensitive financial and personal data, so sending them to a third party materially increases confidentiality risk. The validation narrows file types and OCR mode, which reduces abuse as a generic exfiltration channel, but it does not eliminate the core privacy/security exposure.
)
sys.exit(error_msg)
config.setdefault('SCNET_API_BASE', 'https://api.scnet.cn/api/llm/v1')
return config
def validate_inputs(ocr_type, file_path):
The skill explicitly declares that it will transmit user-provided bank check images to an external API endpoint. Because bank checks contain highly sensitive financial and personal data, sending them off-device to a third party creates a real confidentiality and privacy risk if users are not fully informed, if the endpoint is misconfigured, or if the provider is compromised.
permissions:
- read: local image files provided by the user
- execute: python3 subprocess to run scripts/main.py
- network: transmit the provided image to the configured SCNET_API_BASE (default https://api.scnet.cn/api/llm/v1)
- env: read SCNET_API_KEY and SCNET_API_BASE from the process environment or config/.env
homepage: https://github.com/SCNet-sugon/bank_check_ocr.git
This markdown file is entirely written in Chinese, including the heading and release notes, with no indication that the skill supports other languages or that Chinese-only content is a justified regional requirement. Under the policy, language constraints should be optional or explicitly justified rather than implicitly forced.
No suspicious patterns detected.