High Risk — Risk Score 68/100
Last scan:18 hr ago Rescan
68 /100
moodle-connector
Moodle REST API client, batch downloader, and MCP server for Claude Code integration with SSO support
MCP server and batch downloader contain hardcoded default password 'test-pass' that bypasses documented MOODLE_CRED_PASSWORD requirement, creating credential decryption attack vector.
Skill Namemoodle-connector
Duration55.7s
Enginepi
Do not install this skill
Remove hardcoded default passwords from mcp_server.py and batch_downloader.py. Enforce MOODLE_CRED_PASSWORD environment variable strictly. Do not allow fallback to guessable defaults.

Attack Chain 6 steps

Entry User installs moodle-connector skill and configures MCP server
SKILL.md:184
Escalation User runs 'python moodle_connector.py login' with credentials, which stores encrypted credentials using a password
moodle_connector.py:254
Escalation MCP server (mcp_server.py) ignores MOODLE_CRED_PASSWORD env var and uses hardcoded 'test-pass' as default password for credential decryption
mcp_server.py:37
Escalation Attacker obtains credentials.enc file (e.g., from shared filesystem, backup, or compromised directory)
credentials.enc
Impact Attacker decrypts credentials.enc using known default 'test-pass', extracting stored username, password, and moodle_token
moodle_connector.py:86
Impact Attacker uses extracted Moodle token to access victim's educational data, grades, assignments, and personal information
moodle_connector.py:186

Findings 5 items

Severity Finding Location
High
Hardcoded default password in MCP server bypasses security requirement Credential Theft
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.
password='test-pass'
→ Read MOODLE_CRED_PASSWORD from environment variable and fail if not set. Remove hardcoded default.
mcp_server.py:37
High
Hardcoded default password in batch downloader Credential Theft
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.
default='test-pass'
→ Set default=None and enforce environment variable requirement. Fail clearly if password not provided.
batch_downloader.py:59
Medium
Documentation mandates MOODLE_CRED_PASSWORD but implementation ignores it Doc Mismatch
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.
password='test-pass'
→ Implementation must enforce documented security requirements. Read os.environ.get('MOODLE_CRED_PASSWORD') and raise error if not set.
mcp_server.py:37
Medium
SKILL.md contains plaintext credential example Credential Theft
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.
password='encryption-password'
→ Use a clearly marked placeholder like <YOUR_ENCRYPTION_PASSWORD> instead of a realistic-looking password string.
SKILL.md:130
Low
Username/password storage without explicit user consent Credential Theft
MicrosoftAuthenticator.store_credentials() saves username and password (encrypted) for future logins. While encrypted, users may not be aware credentials are being persisted to disk.
def store_credentials(self, username: str = "", password: str = "", email: str = "") -> None:
→ Document clearly that credentials are stored locally. Consider requiring explicit --save-credentials flag.
moodle_connector.py:260
ResourceDeclaredInferredStatusEvidence
Network READ READ ✓ Aligned All network calls are to declared Moodle API endpoints only
Filesystem WRITE WRITE ✓ Aligned Writes to config.json, credentials.enc, cache/ - all documented
Environment READ READ ✓ Aligned mcp_server.py ignores MOODLE_CRED_PASSWORD env var (SKILL.md:184)
Shell NONE NONE No shell execution found
Skill Invoke NONE NONE No skill invocation found
Clipboard NONE NONE No clipboard access
Browser NONE READ ✓ Aligned Playwright used for SSO flow - declared in SKILL.md features section
Database NONE NONE No direct database access
1 High 7 findings
🔑
High API Key 疑似硬编码凭证
password='encryption-password'
SKILL.md:130
🔗
Medium External URL 外部 URL
https://mytimes.taylors.edu.my/...
SKILL.md:69
🔗
Medium External URL 外部 URL
https://your-idp.example.com
SKILL.md:103
🔗
Medium External URL 外部 URL
https://mytimes.taylors.edu.my
SKILL.md:203
🔗
Medium External URL 外部 URL
https://mytimes.taylors.edu.my/webservice/pluginfile.php/...
SKILL.md:222
🔗
Medium External URL 外部 URL
https://login.microsoftonline.com
moodle_connector.py:143
📧
Info Email 邮箱地址
[email protected]
SKILL.md:280

File Tree

7 files · 56.3 KB · 1655 lines
Python 3f · 1297L Markdown 1f · 295L JSON 2f · 58L Text 1f · 5L
├─ 🐍 batch_downloader.py Python 149L · 4.6 KB
├─ 📋 config.template.json JSON 28L · 685 B
├─ 🐍 mcp_server.py Python 216L · 6.7 KB
├─ 🐍 moodle_connector.py Python 932L · 35.5 KB
├─ 📋 package.json JSON 30L · 777 B
├─ 📄 requirements.txt Text 5L · 74 B
└─ 📝 SKILL.md Markdown 295L · 8.0 KB

Dependencies 4 items

PackageVersionSourceKnown VulnsNotes
requests >=2.31.0 pip No Version range specified, acceptable
cryptography >=41.0.0 pip No Version range specified, acceptable
playwright >=1.40.0 pip No Version range specified, acceptable
mcp >=0.1.0 pip No Version range specified, acceptable

Security Positives

✓ 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