安全决策报告

moodle-connector

MCP server and batch downloader contain hardcoded default password 'test-pass' that bypasses documented MOODLE_CRED_PASSWORD requirement, creating credential decryption attack vector.

安装决策优先 来源: 手动上传 扫描时间: 2026/4/4
文件 7
IOC 7
越权项 0
发现 5
最直接的威胁证据
01
User installs moodle-connector skill and configures MCP server 初始入口 · SKILL.md
02
User runs 'python moodle_connector.py login' with credentials, which stores encrypted credentials using a password setup · moodle_connector.py
03
MCP server (mcp_server.py) ignores MOODLE_CRED_PASSWORD env var and uses hardcoded 'test-pass' as default password for credential decryption vulnerability · mcp_server.py

为什么得出这个结论

2/4 个维度触发
通过
声明与实际能力

声明资源与推断能力基本一致。

阻止
隐藏执行与外联

提取到 1 个高危 IOC 或外联信号。

阻止
攻击链与高危发现

报告包含 6 步攻击链,另有 2 项高危或严重发现。

通过
依赖与供应链卫生

依赖结构存在,但暂未看到明显高危告警。

攻击链

01
User installs moodle-connector skill and configures MCP server

初始入口 · SKILL.md:184

02
User runs 'python moodle_connector.py login' with credentials, which stores encrypted credentials using a password

setup · moodle_connector.py:254

03
MCP server (mcp_server.py) ignores MOODLE_CRED_PASSWORD env var and uses hardcoded 'test-pass' as default password for credential decryption

vulnerability · mcp_server.py:37

04
Attacker obtains credentials.enc file (e.g., from shared filesystem, backup, or compromised directory)

权限提升 · credentials.enc

05
Attacker decrypts credentials.enc using known default 'test-pass', extracting stored username, password, and moodle_token

最终危害 · moodle_connector.py:86

06
Attacker uses extracted Moodle token to access victim's educational data, grades, assignments, and personal information

最终危害 · moodle_connector.py:186

风险分是怎么被拉高的

Hardcoded default password in MCP server +25

mcp_server.py:37 uses password='test-pass' instead of reading MOODLE_CRED_PASSWORD env var

Hardcoded default password in batch downloader +15

batch_downloader.py:59 defaults to 'test-pass' for --password argument

Doc-to-code mismatch on credential requirement +15

SKILL.md mandates MOODLE_CRED_PASSWORD but implementation ignores it and uses default

Undeclared credential decryption capability +10

decrypt_credentials() enables decryption of stored credentials if hardcoded password matches

SKILL.md example contains plaintext credential +5

Documentation shows password='encryption-password' in example code

最关键的证据

高危 凭证窃取

Hardcoded default password in MCP server bypasses security requirement

mcp_server.py hardcodes password='test-pass' when initializing MoodleConnector instead of reading the documented MOODLE_CRED_PASSWORD environment variable. If a user's encrypted credentials were stored using this default password, an attacker who obtains credentials.enc can decrypt it with the known default.

mcp_server.py:37
Read MOODLE_CRED_PASSWORD from environment variable and fail if not set. Remove hardcoded default.
高危 凭证窃取

Hardcoded default password in batch downloader

batch_downloader.py defaults --password argument to 'test-pass'. While it checks for env var, the explicit default makes the system vulnerable if credentials were encrypted with this password.

batch_downloader.py:59
Set default=None and enforce environment variable requirement. Fail clearly if password not provided.
中危 文档欺骗

Documentation mandates MOODLE_CRED_PASSWORD but implementation ignores it

SKILL.md line 184 explicitly states 'REQUIRED: Set MOODLE_CRED_PASSWORD environment variable before starting Claude Code' and shows MOODLE_CRED_PASSWORD in claude_desktop_config.json example. However, mcp_server.py ignores this and uses hardcoded 'test-pass', creating a doc-to-code mismatch.

mcp_server.py:37
Implementation must enforce documented security requirements. Read os.environ.get('MOODLE_CRED_PASSWORD') and raise error if not set.
中危 凭证窃取

SKILL.md contains plaintext credential example

SKILL.md line 130 shows password='encryption-password' in the Python library usage example. While this appears to be documentation, it exposes what could be a commonly used password pattern.

SKILL.md:130
Use a clearly marked placeholder like <YOUR_ENCRYPTION_PASSWORD> instead of a realistic-looking password string.
低危 凭证窃取

Username/password storage without explicit user consent

MicrosoftAuthenticator.store_credentials() saves username and password (encrypted) for future logins. While encrypted, users may not be aware credentials are being persisted to disk.

moodle_connector.py:260
Document clearly that credentials are stored locally. Consider requiring explicit --save-credentials flag.

声明能力 vs 实际能力

网络访问 通过
声明 READ
推断 READ
All network calls are to declared Moodle API endpoints only
文件系统 通过
声明 WRITE
推断 WRITE
Writes to config.json, credentials.enc, cache/ - all documented
环境变量 通过
声明 READ
推断 READ
mcp_server.py ignores MOODLE_CRED_PASSWORD env var (SKILL.md:184)
命令执行 通过
声明 NONE
推断 NONE
No shell execution found
技能调用 通过
声明 NONE
推断 NONE
No skill invocation found
剪贴板 通过
声明 NONE
推断 NONE
No clipboard access
浏览器 通过
声明 NONE
推断 READ
Playwright used for SSO flow - declared in SKILL.md features section
数据库 通过
声明 NONE
推断 NONE
No direct database access

可疑产物与外联

高危 API 密钥
password='encryption-password'

SKILL.md:130

中危 外部 URL
https://mytimes.taylors.edu.my/...

SKILL.md:69

中危 外部 URL
https://your-idp.example.com

SKILL.md:103

中危 外部 URL
https://mytimes.taylors.edu.my

SKILL.md:203

中危 外部 URL
https://mytimes.taylors.edu.my/webservice/pluginfile.php/...

SKILL.md:222

中危 外部 URL
https://login.microsoftonline.com

moodle_connector.py:143

提示 邮箱
[email protected]

SKILL.md:280

依赖与供应链

包名版本来源漏洞备注
requests >=2.31.0 pip Version range specified, acceptable
cryptography >=41.0.0 pip Version range specified, acceptable
playwright >=1.40.0 pip Version range specified, acceptable
mcp >=0.1.0 pip Version range specified, acceptable

文件构成

7 个文件 · 1655 行
Python 3 个文件 · 1297 行Markdown 1 个文件 · 295 行JSON 2 个文件 · 58 行Text 1 个文件 · 5 行
需关注文件 · 4
moodle_connector.py Python · 932 行
Username/password storage without explicit user consent · https://login.microsoftonline.com
SKILL.md Markdown · 295 行
SKILL.md contains plaintext credential example · password='encryption-password' · https://mytimes.taylors.edu.my/... · https://your-idp.example.com · https://mytimes.taylors.edu.my · https://mytimes.taylors.edu.my/webservice/pluginfile.php/... · [email protected]
mcp_server.py Python · 216 行
Hardcoded default password in MCP server bypasses security requirement · Documentation mandates MOODLE_CRED_PASSWORD but implementation ignores it
batch_downloader.py Python · 149 行
Hardcoded default password in batch downloader
其他文件 · package.json · config.template.json · requirements.txt

安全亮点

Strong encryption: PBKDF2 with 480K iterations + Fernet (cryptographically sound)
No network exfiltration or C2 communication detected
No obfuscation techniques (base64, eval, etc.) found
Error sanitization in MCP server prevents internal detail leakage to clients
No suspicious file path access (no ~/.ssh, ~/.aws, .env reading)
No remote script execution (no curl|bash, wget|sh patterns)
Cache TTL prevents unbounded storage
No subprocess or shell execution beyond legitimate Playwright browser automation