T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:78- Finding
Unrestricted OCR Endpoint Can Expose API Credentials and Sensitive Documents
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a legitimate OCR purpose, but it can upload sensitive business documents and the API token to a configurable, unvalidated endpoint.
Review before installing. Use only with documents you are authorized to send to Scnet or another explicitly trusted OCR endpoint. Keep `SCNET_API_BASE` at the official HTTPS Scnet URL unless you have validated the replacement endpoint, and store the API key only in the local config file with restrictive permissions.
scripts/main.py:78Unrestricted OCR Endpoint Can Expose API Credentials and Sensitive Documents
SKILL.md:72Runtime Dependency Installation Is Unpinned and Lacks Integrity Verification
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"
# --- 新增:重试配置 ---
MAX_RETRIES = 3 # 最大重试次数
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# --------------------
def load_config():
"""从 .env 文件加载配置,若文件不存在则抛出友好错误"""
if not ENV_FILE.exists():
error_msg = (
"\n===============================================\n"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# --------------------
def load_config():
"""从 .env 文件加载配置,若文件不存在则抛出友好错误"""
if not ENV_FILE.exists():
error_msg = (
"\n===============================================\n"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# --------------------
def load_config():
"""从 .env 文件加载配置,若文件不存在则抛出友好错误"""
if not ENV_FILE.exists():
error_msg = (
"\n===============================================\n"
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 documentation indicates capabilities that read local files, execute Python, and send data over the network, but it does not declare an explicit tool scope such as permissions or allowed-tools. In an agent environment, this weakens least-privilege controls and can allow the skill to be invoked with broader capabilities than users expect, especially when processing sensitive local documents.
The skill does not clearly warn that local license images and the extracted structured data will be sent to an external OCR service. Since enterprise licenses may contain regulated or sensitive company information, omission of this disclosure can cause users to unknowingly transmit confidential documents off-host.
This finding reflects a real external transmission path to the Scnet API. External transmission is expected for a cloud OCR skill, but it remains security-relevant because the uploaded content consists of local document images and extracted license data that may be sensitive.
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 auto-trigger guidance is broad: the AI is told to activate the skill based on description keywords, and the example prompts are generic enough that ordinary conversation about license images could trigger the skill. Because this skill reads a local file path and transmits document contents externally, loose triggering increases the chance of unintended processing or exfiltration of sensitive business documents.
The configuration section again confirms an external API base URL, reinforcing that document data is transmitted off the local system. In context this is functional rather than malicious, but it is still a genuine exposure point because users may not realize OCR results and source images leave the environment.
| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| SCNET_API_KEY | 必需 | Scnet API 密钥 |
| SCNET_API_BASE | https://api.scnet.cn/api/llm/v1 | API 基础地址(一般无需修改) |
### 输出
The documented API endpoint is an external service, so use of this skill necessarily transmits document images and derived OCR content outside the local environment. External transmission is not inherently malicious, but in this skill's context it is security-relevant because the processed documents are licenses and financial/business records containing sensitive identifying information.
# Sugon-Scnet OCR API 文档摘要
## 接口地址
`POST https://api.scnet.cn/api/llm/v1/ocr/recognize`
## 请求头
- `Content-Type: multipart/form-data`
The document describes sending uploaded files containing enterprise licenses and receiving OCR-extracted fields from an external OCR service, but provides no warning about privacy, retention, consent, or third-party handling. Because these examples include sensitive business and personal data such as legal representatives, addresses, account numbers, and license identifiers, this creates a real data-exposure risk if operators use the skill without understanding that regulated documents leave the local trust boundary.
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 and an API bearer token to an external third-party OCR endpoint at api.scnet.cn. This is a real data exfiltration boundary: enterprise license images may contain sensitive business or personal information, and the code provides no allowlist enforcement, user consent check, or data minimization before transmission.
)
sys.exit(error_msg)
config.setdefault('SCNET_API_BASE', 'https://api.scnet.cn/api/llm/v1')
return config
def recognize_with_retry(ocr_type, file_path, config, retry_count=0):
The manifest description and comments are written entirely in Chinese, indicating a fixed language/locale for the skill experience with no documented user choice or region-specific justification. This can violate language/locale policy when a skill implicitly restricts usage to one language without opt-in.
This markdown file uses Chinese for the title and entry text, which can constitute a language policy violation if the skill forces a specific language without user opt-in. There is no indication in the file that the language is optional, user-selected, or justified as region-specific.
This markdown file includes executable Git commands that change the local repository remote, rename the branch, and push content to a remote origin, but it provides no accompanying warning about those side effects. For markdown files, SQP-2 applies when documentation omits warnings about actions that can affect user data or system state.
No suspicious patterns detected.