Skill Trust Decision

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.

Install decision first Source: Manual upload Scanned: Apr 4, 2026
Files 7
Artifacts 7
Violations 0
Findings 5
Most direct threat evidence
01
User installs moodle-connector skill and configures MCP server Entry · 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

Why this conclusion was reached

2/4 dimensions flagged
Pass
Declared vs actual capability

Declared resources and inferred behavior are broadly aligned.

Block
Hidden execution and egress

1 high-risk artifacts or egress signals were extracted.

Block
Attack chain and severe findings

The report includes 6 attack-chain steps and 2 severe findings.

Pass
Dependencies and supply chain hygiene

Dependencies are present but no obvious high-risk issue stands out.

Attack Chain

01
User installs moodle-connector skill and configures MCP server

Entry · 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)

Escalation · credentials.enc

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

Impact · moodle_connector.py:86

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

Impact · moodle_connector.py:186

What drove the risk score up

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

Most important evidence

High Credential Theft

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.
High Credential Theft

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.
Medium Doc Mismatch

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.
Medium Credential Theft

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.
Low Credential Theft

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.

Declared capability vs actual capability

Network Pass
Declared READ
Inferred READ
All network calls are to declared Moodle API endpoints only
Filesystem Pass
Declared WRITE
Inferred WRITE
Writes to config.json, credentials.enc, cache/ - all documented
Environment Pass
Declared READ
Inferred READ
mcp_server.py ignores MOODLE_CRED_PASSWORD env var (SKILL.md:184)
Shell Pass
Declared NONE
Inferred NONE
No shell execution found
Skill Invoke Pass
Declared NONE
Inferred NONE
No skill invocation found
Clipboard Pass
Declared NONE
Inferred NONE
No clipboard access
Browser Pass
Declared NONE
Inferred READ
Playwright used for SSO flow - declared in SKILL.md features section
Database Pass
Declared NONE
Inferred NONE
No direct database access

Suspicious artifacts and egress

High API Key
password='encryption-password'

SKILL.md:130

Medium External URL
https://mytimes.taylors.edu.my/...

SKILL.md:69

Medium External URL
https://your-idp.example.com

SKILL.md:103

Medium External URL
https://mytimes.taylors.edu.my

SKILL.md:203

Medium External URL
https://mytimes.taylors.edu.my/webservice/pluginfile.php/...

SKILL.md:222

Medium External URL
https://login.microsoftonline.com

moodle_connector.py:143

Info Email
[email protected]

SKILL.md:280

Dependencies and supply chain

PackageVersionSourceKnown vulnNotes
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

File composition

7 files · 1655 lines
Python 3 files · 1297 linesMarkdown 1 files · 295 linesJSON 2 files · 58 linesText 1 files · 5 lines
Files of concern · 4
moodle_connector.py Python · 932 lines
Username/password storage without explicit user consent · https://login.microsoftonline.com
SKILL.md Markdown · 295 lines
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 lines
Hardcoded default password in MCP server bypasses security requirement · Documentation mandates MOODLE_CRED_PASSWORD but implementation ignores it
batch_downloader.py Python · 149 lines
Hardcoded default password in batch downloader
Other files · package.json · config.template.json · requirements.txt

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