可疑 — 风险评分 45/100
上次扫描:1 天前 重新扫描
45 /100
rewrite_question
补全上下文并重写用户提问
Skill claims to only rewrite queries but secretly connects to an external IP (47.77.199.56), embeds a default admin JWT credential, queries a Milvus database, and executes Python subprocesses — all undeclared.
技能名称rewrite_question
分析耗时65.5s
引擎pi
谨慎使用
Block deployment. The hardcoded external IP, embedded JWT token, undeclared Milvus access, and subprocess spawning represent significant hidden functionality that directly contradicts the SKILL.md declaration of network:NONE and no database access.

安全发现 7 项

严重性 安全发现 位置
高危
Network capability declared as NONE but actual traffic exists 文档欺骗
SKILL.md declares 'network: NONE' yet rewrite_question.py:472 makes HTTP POST requests to an externally hosted Gemini API at the hardcoded IP 47.77.199.56. The skill description says it only 'rephrases questions' with no mention of LLM API calls or external network communication.
resp = client.post(self.api_url, json=payload, headers=headers)
→ Update SKILL.md to declare network:READ for LLM API calls. Consider documenting the external service endpoint.
rewrite_question.py:472
高危
Default JWT token embedded in source code 凭证窃取
A default JWT token (BI-eyJ...Ij8pY) is hardcoded in _get_gemini_config() containing userId:'admin' and an expiration of March 2027. While this may be an internal service token, embedding credentials in source code is a security risk and could leak in logs or version control.
os.getenv('GEMINI_TOKEN', _default_token)  # _default_token is the embedded JWT
→ Remove the embedded JWT from source code. Require GEMINI_TOKEN to be set via environment or .env file only.
rewrite_question.py:562
高危
Hardcoded external IP address for all LLM communication 数据外泄
The Gemini API endpoint defaults to a raw IP address (47.77.199.56) rather than a DNS hostname. This IP is in Chinese address space (47.77.x.x). The base URL is not configurable via SKILL.md or documented, and all queries — potentially including user data and conversation context — are sent to this address.
base_url = os.getenv('GEMINI_API_URL', 'http://47.77.199.56/api/v1beta')
→ Use a DNS-resolvable hostname instead of a raw IP. Declare the network endpoint in SKILL.md. Consider whether data sent to this external service is within compliance.
rewrite_question.py:559
中危
Undeclared Milvus database access 权限提升
The skill connects to a Milvus vector database (rewrite_question.py:584-596) to fetch QA pairs. The connection supports user/password authentication. SKILL.md declares database:NONE and no mention of database access anywhere in the documentation.
from pymilvus import MilvusClient; client.query(collection_name=collection, ...)
→ Declare database:READ access in SKILL.md if Milvus access is intentional. Document which Milvus collection is queried and what data is retrieved.
rewrite_question.py:584
中危
Undeclared Python subprocess execution via Node.js wrapper 代码执行
index.js uses child_process.spawn to execute Python code inline, passing the skill directory and JSON payload as arguments. This is shell/code execution that is not declared in SKILL.md (shell:NONE).
spawn(PYTHON_BIN, ['-c', script, skillDir])
→ Document the shell:WRITE capability if subprocess execution is intentional, or refactor to use a different IPC mechanism.
index.js:62
中危
Hidden SQL bypass via QA pair matching not documented 文档欺骗
Path A (rewrite_question.py:227-237) silently outputs SQL when a user query matches a QA pair in Milvus — bypassing the normal rewriting flow entirely. The rewritten query is unchanged, but matched_sql contains a full SQL statement. This 'shortcut' behavior is not described in SKILL.md.
if matched_qa: ... return RewriteOutput(..., is_qa_matched=True, matched_sql=updated_sql)
→ Document the QA pair matching behavior in SKILL.md, including that SQL can be directly output.
rewrite_question.py:227
低危
No dependency pinning — uses httpx, pymilvus, python-dotenv without versions 供应链
No requirements.txt, pyproject.toml, or package.json exists. The code imports httpx, pymilvus, python-dotenv with no version constraints, making it vulnerable to dependency confusion or supply chain attacks.
import httpx
→ Create a requirements.txt or pyproject.toml with pinned versions for all dependencies.
rewrite_question.py:1
资源类型声明权限推断权限状态证据
文件系统 NONE WRITE ✓ 一致 index.js:61 — writes JSON output to file via Python subprocess
网络访问 NONE WRITE ✗ 越权 rewrite_question.py:472 — httpx.Client POST to http://47.77.199.56; SKILL.md:net…
命令执行 NONE WRITE ✗ 越权 index.js:62 — spawn(PYTHON_BIN, ['-c', script, skillDir])
环境变量 NONE READ ✓ 一致 rewrite_question.py:556 — os.getenv for GEMINI_API_KEY, MILVUS_HOST, MILVUS_PASS…
技能调用 NONE NONE No cross-skill invocation found
剪贴板 NONE NONE No clipboard access
浏览器 NONE NONE No browser access
数据库 NONE WRITE ✗ 越权 rewrite_question.py:584-596 — PyMilvusClient query() reads from Milvus; supports…
1 高危 2 项发现
📡
高危 IP 地址 硬编码 IP 地址
47.77.199.56
rewrite_question.py:559
🔗
中危 外部 URL 外部 URL
http://47.77.199.56/api/v1beta
rewrite_question.py:559

目录结构

3 文件 · 41.2 KB · 943 行
Python 1f · 769L JavaScript 1f · 128L Markdown 1f · 46L
├─ 📜 index.js JavaScript 128L · 4.5 KB
├─ 🐍 rewrite_question.py Python 769L · 35.3 KB
└─ 📝 SKILL.md Markdown 46L · 1.4 KB

依赖分析 4 项

包名版本来源已知漏洞备注
httpx unpinned import No requirements.txt or pyproject.toml; httpx version uncontrolled
pymilvus unpinned import Used for Milvus DB access; optional import with try/except
python-dotenv unpinned import Used for .env loading; optional import with try/except
asyncio built-in stdlib Standard library, no risk

安全亮点

✓ No base64-encoded payloads piped to shell
✓ No direct credential exfiltration code (credentials sent to intended Gemini API endpoint, not third-party)
✓ No reverse shell, C2, or ransomware patterns found
✓ No cron/scheduled task or persistence mechanisms
✓ No prompt injection instructions in comments
✓ No ~/.ssh, ~/.aws, or .env file reading beyond standard dotenv loading