Cross-site Scripting (XSS) - Stored in usememos/memos
Description
Cross-site Scripting (XSS) - Stored in GitHub repository usememos/memos prior to 0.9.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Stored XSS in usememos/memos prior to 0.9.0 allows attackers to inject arbitrary JavaScript via crafted resource uploads.
Vulnerability
Overview
CVE-2022-4691 is a stored cross-site scripting (XSS) vulnerability in the open-source note-taking application usememos/memos, affecting versions prior to 0.9.0. The root cause lies in how the application serves uploaded resources: when a resource's MIME type is text/html, the server originally forced the Content-Type header to text/plain as a mitigation. However, this override was removed in a later commit, and the server now serves resources with their original Content-Type [1][3]. This allows an attacker to upload a file with a crafted Content-Type (e.g., text/html) that, when accessed by other users, is rendered as HTML in the browser, enabling script execution.
Exploitation
An attacker must have the ability to upload resources to the memos instance (e.g., as a registered user). By uploading a file with a malicious Content-Type header—such as text/html—and containing embedded JavaScript, the resource is stored on the server. When another user views the resource (e.g., via a direct link or embedded in a memo), the browser interprets the response as HTML and executes the injected script. No additional authentication is required beyond the upload capability, and the attack can be triggered by simply visiting the resource URL [4].
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the victim's session. This can lead to theft of sensitive data (e.g., session cookies, authentication tokens), defacement of the application, or further actions such as performing operations on behalf of the victim. Since the XSS is stored, the payload persists until the resource is removed, affecting all users who view the malicious resource.
Mitigation
The vulnerability is fixed in memos version 0.9.0. The fix, introduced in commit c07b4a57caa89905e54b800f4d8fb720bbf5bf82, removes the problematic Content-Type override and adds a secure middleware that likely enforces proper security headers (e.g., Content-Security-Policy) to prevent script execution [3]. Users are strongly advised to upgrade to the latest version. No workarounds are documented, and the vulnerability is not currently listed in CISA's Known Exploited Vulnerabilities catalog.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/usememos/memosGo | < 0.9.0 | 0.9.0 |
Affected products
2- usememos/usememos/memosv5Range: unspecified
Patches
1c07b4a57caa8feat: add secure middleware (#832)
2 files changed · +5 −6
server/resource.go+1 −6 modified@@ -7,7 +7,6 @@ import ( "net/http" "net/url" "strconv" - "strings" "time" "github.com/usememos/memos/api" @@ -263,11 +262,7 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to fetch resource ID: %v", resourceID)).SetInternal(err) } - if strings.HasPrefix(resource.Type, echo.MIMETextHTML) { - c.Response().Writer.Header().Set("Content-Type", echo.MIMETextPlain) - } else { - c.Response().Writer.Header().Set("Content-Type", resource.Type) - } + c.Response().Writer.Header().Set("Content-Type", resource.Type) c.Response().Writer.WriteHeader(http.StatusOK) c.Response().Writer.Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable") if _, err := c.Response().Writer.Write(resource.Blob); err != nil {
server/server.go+4 −0 modified@@ -44,6 +44,10 @@ func NewServer(profile *profile.Profile) *Server { Timeout: 30 * time.Second, })) + e.Use(middleware.SecureWithConfig(middleware.SecureConfig{ + ContentSecurityPolicy: "default-src 'self'", + })) + embedFrontend(e) // In dev mode, set the const secret key to make signin session persistence.
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.