High severityNVD Advisory· Published Aug 20, 2024· Updated Jan 9, 2025
GHSL-2024-034: memos CORS Misconfiguration in server.go
CVE-2024-41659
Description
memos is a privacy-first, lightweight note-taking service. A CORS misconfiguration exists in memos 0.20.1 and earlier where an arbitrary origin is reflected with Access-Control-Allow-Credentials set to true. This may allow an attacking website to make a cross-origin request, allowing the attacker to read private information or make privileged changes to the system as the vulnerable user account. This vulnerability is fixed in 0.21.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/usememos/memosGo | < 0.21.0 | 0.21.0 |
Affected products
1Patches
18101a5e0b162chore: add origin flag to config cors
3 files changed · +32 −12
bin/memos/main.go+16 −9 modified@@ -31,18 +31,19 @@ const ( ) var ( - profile *_profile.Profile - mode string - addr string - port int - data string - driver string - dsn string - serveFrontend bool + profile *_profile.Profile + mode string + addr string + port int + data string + driver string + dsn string + serveFrontend bool + allowedOrigins []string rootCmd = &cobra.Command{ Use: "memos", - Short: `An open-source, self-hosted memo hub with knowledge management and social networking.`, + Short: `An open source, lightweight note-taking service. Easily capture and share your great thoughts.`, Run: func(_cmd *cobra.Command, _args []string) { ctx, cancel := context.WithCancel(context.Background()) dbDriver, err := db.NewDBDriver(profile) @@ -114,6 +115,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&driver, "driver", "", "", "database driver") rootCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "database source name(aka. DSN)") rootCmd.PersistentFlags().BoolVarP(&serveFrontend, "frontend", "", true, "serve frontend files") + rootCmd.PersistentFlags().StringArrayVarP(&allowedOrigins, "origins", "", []string{}, "CORS allowed domain origins") err := viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode")) if err != nil { @@ -143,12 +145,17 @@ func init() { if err != nil { panic(err) } + err = viper.BindPFlag("origins", rootCmd.PersistentFlags().Lookup("origins")) + if err != nil { + panic(err) + } viper.SetDefault("mode", "demo") viper.SetDefault("driver", "sqlite") viper.SetDefault("addr", "") viper.SetDefault("port", 8081) viper.SetDefault("frontend", true) + viper.SetDefault("origins", []string{}) viper.SetEnvPrefix("memos") }
server/profile/profile.go+2 −0 modified@@ -32,6 +32,8 @@ type Profile struct { Version string `json:"version"` // Frontend indicate the frontend is enabled or not Frontend bool `json:"-"` + // Origins is the list of allowed origins + Origins []string `json:"-"` } func (p *Profile) IsDev() bool {
server/server.go+14 −3 modified@@ -49,7 +49,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store } // Register CORS middleware. - e.Use(CORSMiddleware()) + e.Use(CORSMiddleware(s.Profile.Origins)) serverID, err := s.getSystemServerID(ctx) if err != nil { @@ -160,7 +160,7 @@ func grpcRequestSkipper(c echo.Context) bool { return strings.HasPrefix(c.Request().URL.Path, "/memos.api.v2.") } -func CORSMiddleware() echo.MiddlewareFunc { +func CORSMiddleware(origins []string) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { if grpcRequestSkipper(c) { @@ -170,7 +170,18 @@ func CORSMiddleware() echo.MiddlewareFunc { r := c.Request() w := c.Response().Writer - w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) + requestOrigin := r.Header.Get("Origin") + if len(origins) == 0 { + w.Header().Set("Access-Control-Allow-Origin", requestOrigin) + } else { + for _, origin := range origins { + if origin == requestOrigin { + w.Header().Set("Access-Control-Allow-Origin", origin) + break + } + } + } + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") w.Header().Set("Access-Control-Allow-Credentials", "true")
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-p4fx-qf2h-jpmjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-41659ghsaADVISORY
- securitylab.github.com/advisories/GHSL-2024-034_memosghsaADVISORY
- github.com/usememos/memos/blob/v0.20.1/server/server.goghsax_refsource_MISCWEB
- github.com/usememos/memos/commit/8101a5e0b162044c16385bee4f12a4a653d050b9ghsax_refsource_MISCWEB
- securitylab.github.com/advisories/GHSL-2024-034_memos/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.