Moodle Web Services Skill
AdvisoryAudited by VirusTotal on Mar 21, 2026.
Overview
Type: OpenClaw Skill Name: moodle-ws Version: 1.3.1 The moodle-ws skill bundle provides legitimate Moodle 4.x administration capabilities via REST API, including course management, user enrollment, and messaging. While it contains scripts for destructive actions like deleting empty courses and categories (e.g., scripts/mantenimiento/borrar_vacios.py), these are clearly labeled as maintenance tools and align with the stated purpose. The code follows standard OpenClaw security practices by utilizing a local secrets file (~/.openclaw/workspace/secrets/moodle-ws.json) and includes explicit instructions in SKILL.md to prevent token exposure in chat.
Findings (0)
Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.
A user or agent could remove Moodle courses if this script is run with a sufficiently privileged token.
The included helper deletes Moodle courses using the configured token. SKILL.md describes creating courses, enrolling users, messaging, grading, and listing, but does not disclose course deletion or a confirmation/dry-run workflow.
# Lee /tmp/vacios.json y borra esos cursos en Moodle ... call("core_course_delete_courses", {"courseids[0]": cid})Remove this from the general skill or document it as a separate destructive maintenance action requiring explicit user approval, dry-run output, backups, and a narrowly scoped token.
Courses could be deleted because of a bad temporary file or assumptions that only fit the author's Moodle site.
The empty-course list is built using hardcoded site-specific exclusions and written to /tmp; the delete script later consumes /tmp/vacios.json, so a stale, tampered, or misclassified file can cascade into course deletion.
excluir = ["info@campusinda.net", "profe-ia@campusinda.net"] ... json.dump(sin, open("/tmp/vacios.json","w"))Use a private skill-owned state path, validate course IDs immediately before deletion, remove site-specific exclusions or make them configurable, and require a final human-approved deletion list.
A mistaken invocation could send official Moodle messages to many students.
The helper can send internal messages to students across all Moodle courses. Messaging is part of the stated purpose, but this broad all-course broadcast path has no built-in confirmation or scoping step.
def seguimiento_todos(config, texto): ... for curso in cursos: ... for alumno in reales: ... enviar_mensaje(config, uid, msg)
Require explicit confirmation showing recipient counts and course list before bulk sends, and prefer course-scoped messaging by default.
Users may grant a broader Moodle token than they realize, enabling destructive actions beyond normal create/list/enroll workflows.
This requires delete-category privileges, including recursive deletion behavior, but SKILL.md's enabled-function list does not disclose delete-course or delete-category permissions.
call("core_course_delete_categories", { ... "categories[0][recursive]": 1 })Declare every Moodle web-service function the token needs, use least-privilege tokens per workflow, and omit delete permissions unless a separately approved maintenance mode is enabled.
Users may not see the required token/config setup from registry metadata alone.
The registry metadata does not declare the Moodle credential/config path or Python dependency that SKILL.md and the scripts rely on. This appears to be a packaging/setup gap, not hidden auto-execution.
Primary credential: none; Required config paths: none; No install spec — this is an instruction-only skill.
Update metadata to declare the Moodle secret/config path, expected token scope, and required Python dependencies.
