VYPR
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.

PackageAffected versionsPatched versions
github.com/usememos/memosGo
< 0.21.00.21.0

Affected products

1

Patches

1
8101a5e0b162

chore: add origin flag to config cors

https://github.com/usememos/memosStevenApr 7, 2024via ghsa
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

News mentions

0

No linked articles in our index yet.