VYPR
Moderate severityNVD Advisory· Published Apr 26, 2024· Updated Aug 2, 2024

Detailed error discloses full file path with dev mode off

CVE-2024-32046

Description

Mattermost versions 9.6.x <= 9.6.0, 9.5.x <= 9.5.2, 9.4.x <= 9.4.4 and 8.1.x <= 8.1.11 fail to remove detailed error messages in API requests even if the developer mode is off which allows an attacker to get information about the server such as the full path were files are stored

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/mattermost/mattermost-serverGo
>= 8.1.0, < 8.1.128.1.12
github.com/mattermost/mattermost-serverGo
>= 9.5.0, < 9.5.39.5.3
github.com/mattermost/mattermost-serverGo
>= 9.6.0-rc1, < 9.6.19.6.1
github.com/mattermost/mattermost-serverGo
>= 9.4.0, < 9.4.59.4.5

Affected products

1

Patches

4
93738756ff79

[MM-57070] Remove detailed_error from errors when not in dev mode (#26414) (#26531)

https://github.com/mattermost/mattermostChristopher PoileMar 20, 2024via ghsa
6 files changed · +55 5
  • server/channels/api4/post_test.go+9 0 modified
    @@ -1269,6 +1269,15 @@ func TestPatchPost(t *testing.T) {
     	})
     
     	t.Run("invalid requests", func(t *testing.T) {
    +		var origEnableDeveloper bool
    +		th.App.UpdateConfig(func(cfg *model.Config) {
    +			origEnableDeveloper = *cfg.ServiceSettings.EnableDeveloper
    +			*cfg.ServiceSettings.EnableDeveloper = true
    +		})
    +		defer th.App.UpdateConfig(func(cfg *model.Config) {
    +			*cfg.ServiceSettings.EnableDeveloper = origEnableDeveloper
    +		})
    +
     		r, err := client.DoAPIPut(context.Background(), "/posts/"+post.Id+"/patch", "garbage")
     		require.EqualError(t, err, ": Invalid or missing post in request body., invalid character 'g' looking for beginning of value")
     		require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code")
    
  • server/channels/app/platform/websocket_router.go+1 1 modified
    @@ -107,7 +107,7 @@ func returnWebSocketError(ps *PlatformService, conn *WebConn, r *model.WebSocket
     		return
     	}
     
    -	err.DetailedError = ""
    +	err.WipeDetailed()
     	errorResp := model.NewWebSocketError(r.Seq, err)
     	hub.SendMessage(conn, errorResp)
     }
    
  • server/channels/web/handlers.go+2 2 modified
    @@ -368,14 +368,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     
     		// Block out detailed error when not in developer mode
     		if !*c.App.Config().ServiceSettings.EnableDeveloper {
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     		}
     
     		// Sanitize all 5xx error messages in hardened mode
     		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err.StatusCode >= 500 {
     			c.Err.Id = ""
     			c.Err.Message = "Internal Server Error"
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     			c.Err.StatusCode = 500
     			c.Err.Where = ""
     			c.Err.IsOAuth = false
    
  • server/channels/wsapi/websocket_handler.go+2 2 modified
    @@ -41,7 +41,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", sessionErr.SystemMessage(i18n.T)),
     			mlog.Err(sessionErr),
     		)
    -		sessionErr.DetailedError = ""
    +		sessionErr.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, sessionErr)
     		hub.SendMessage(conn, errResp)
     		return
    @@ -63,7 +63,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", err.SystemMessage(i18n.T)),
     			mlog.Err(err),
     		)
    -		err.DetailedError = ""
    +		err.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, err)
     		hub.SendMessage(conn, errResp)
     		return
    
  • server/public/model/utils.go+5 0 modified
    @@ -363,6 +363,11 @@ func (er *AppError) Wrap(err error) *AppError {
     	return er
     }
     
    +func (er *AppError) WipeDetailed() {
    +	er.wrapped = nil
    +	er.DetailedError = ""
    +}
    +
     // AppErrorFromJSON will decode the input and return an AppError
     func AppErrorFromJSON(data io.Reader) *AppError {
     	str := ""
    
  • server/public/model/utils_test.go+36 0 modified
    @@ -150,6 +150,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Detailed", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot)
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -161,6 +173,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Detailed + Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -171,6 +195,18 @@ func TestAppErrorSerialize(t *testing.T) {
     
     		require.EqualError(t, berr, aerr.Error())
     	})
    +
    +	t.Run("Detailed + Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
     }
     
     func TestCopyStringMap(t *testing.T) {
    
2a48b5b3428c

[MM-57070] Remove detailed_error from errors when not in dev mode (#26414) (#26530)

https://github.com/mattermost/mattermostChristopher PoileMar 20, 2024via ghsa
6 files changed · +55 5
  • server/channels/api4/post_test.go+9 0 modified
    @@ -1269,6 +1269,15 @@ func TestPatchPost(t *testing.T) {
     	})
     
     	t.Run("invalid requests", func(t *testing.T) {
    +		var origEnableDeveloper bool
    +		th.App.UpdateConfig(func(cfg *model.Config) {
    +			origEnableDeveloper = *cfg.ServiceSettings.EnableDeveloper
    +			*cfg.ServiceSettings.EnableDeveloper = true
    +		})
    +		defer th.App.UpdateConfig(func(cfg *model.Config) {
    +			*cfg.ServiceSettings.EnableDeveloper = origEnableDeveloper
    +		})
    +
     		r, err := client.DoAPIPut(context.Background(), "/posts/"+post.Id+"/patch", "garbage")
     		require.EqualError(t, err, ": Invalid or missing post in request body., invalid character 'g' looking for beginning of value")
     		require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code")
    
  • server/channels/app/platform/websocket_router.go+1 1 modified
    @@ -107,7 +107,7 @@ func returnWebSocketError(ps *PlatformService, conn *WebConn, r *model.WebSocket
     		return
     	}
     
    -	err.DetailedError = ""
    +	err.WipeDetailed()
     	errorResp := model.NewWebSocketError(r.Seq, err)
     	hub.SendMessage(conn, errorResp)
     }
    
  • server/channels/web/handlers.go+2 2 modified
    @@ -376,14 +376,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     
     		// Block out detailed error when not in developer mode
     		if !*c.App.Config().ServiceSettings.EnableDeveloper {
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     		}
     
     		// Sanitize all 5xx error messages in hardened mode
     		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err.StatusCode >= 500 {
     			c.Err.Id = ""
     			c.Err.Message = "Internal Server Error"
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     			c.Err.StatusCode = 500
     			c.Err.Where = ""
     			c.Err.IsOAuth = false
    
  • server/channels/wsapi/websocket_handler.go+2 2 modified
    @@ -41,7 +41,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", sessionErr.SystemMessage(i18n.T)),
     			mlog.Err(sessionErr),
     		)
    -		sessionErr.DetailedError = ""
    +		sessionErr.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, sessionErr)
     		hub.SendMessage(conn, errResp)
     		return
    @@ -63,7 +63,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", err.SystemMessage(i18n.T)),
     			mlog.Err(err),
     		)
    -		err.DetailedError = ""
    +		err.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, err)
     		hub.SendMessage(conn, errResp)
     		return
    
  • server/public/model/utils.go+5 0 modified
    @@ -333,6 +333,11 @@ func (er *AppError) Wrap(err error) *AppError {
     	return er
     }
     
    +func (er *AppError) WipeDetailed() {
    +	er.wrapped = nil
    +	er.DetailedError = ""
    +}
    +
     // AppErrorFromJSON will decode the input and return an AppError
     func AppErrorFromJSON(data io.Reader) *AppError {
     	str := ""
    
  • server/public/model/utils_test.go+36 0 modified
    @@ -150,6 +150,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Detailed", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot)
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -161,6 +173,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Detailed + Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -171,6 +195,18 @@ func TestAppErrorSerialize(t *testing.T) {
     
     		require.EqualError(t, berr, aerr.Error())
     	})
    +
    +	t.Run("Detailed + Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
     }
     
     func TestCopyStringMap(t *testing.T) {
    
c84c25b20c8b

[MM-57070] Remove detailed_error from errors when not in dev mode (#26414) (#26529)

https://github.com/mattermost/mattermostChristopher PoileMar 20, 2024via ghsa
6 files changed · +55 5
  • server/channels/api4/post_test.go+9 0 modified
    @@ -1497,6 +1497,15 @@ func TestPatchPost(t *testing.T) {
     	})
     
     	t.Run("invalid requests", func(t *testing.T) {
    +		var origEnableDeveloper bool
    +		th.App.UpdateConfig(func(cfg *model.Config) {
    +			origEnableDeveloper = *cfg.ServiceSettings.EnableDeveloper
    +			*cfg.ServiceSettings.EnableDeveloper = true
    +		})
    +		defer th.App.UpdateConfig(func(cfg *model.Config) {
    +			*cfg.ServiceSettings.EnableDeveloper = origEnableDeveloper
    +		})
    +
     		r, err := client.DoAPIPut(context.Background(), "/posts/"+post.Id+"/patch", "garbage")
     		require.EqualError(t, err, "Invalid or missing post in request body., invalid character 'g' looking for beginning of value")
     		require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code")
    
  • server/channels/app/platform/websocket_router.go+1 1 modified
    @@ -134,7 +134,7 @@ func returnWebSocketError(ps *PlatformService, conn *WebConn, r *model.WebSocket
     		return
     	}
     
    -	err.DetailedError = ""
    +	err.WipeDetailed()
     	errorResp := model.NewWebSocketError(r.Seq, err)
     	hub.SendMessage(conn, errorResp)
     }
    
  • server/channels/web/handlers.go+2 2 modified
    @@ -376,14 +376,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     
     		// Block out detailed error when not in developer mode
     		if !*c.App.Config().ServiceSettings.EnableDeveloper {
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     		}
     
     		// Sanitize all 5xx error messages in hardened mode
     		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err.StatusCode >= 500 {
     			c.Err.Id = ""
     			c.Err.Message = "Internal Server Error"
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     			c.Err.StatusCode = 500
     			c.Err.Where = ""
     			c.Err.IsOAuth = false
    
  • server/channels/wsapi/websocket_handler.go+2 2 modified
    @@ -41,7 +41,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", sessionErr.SystemMessage(i18n.T)),
     			mlog.Err(sessionErr),
     		)
    -		sessionErr.DetailedError = ""
    +		sessionErr.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, sessionErr)
     		hub.SendMessage(conn, errResp)
     		return
    @@ -63,7 +63,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", err.SystemMessage(i18n.T)),
     			mlog.Err(err),
     		)
    -		err.DetailedError = ""
    +		err.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, err)
     		hub.SendMessage(conn, errResp)
     		return
    
  • server/public/model/utils.go+5 0 modified
    @@ -336,6 +336,11 @@ func (er *AppError) Wrap(err error) *AppError {
     	return er
     }
     
    +func (er *AppError) WipeDetailed() {
    +	er.wrapped = nil
    +	er.DetailedError = ""
    +}
    +
     // AppErrorFromJSON will decode the input and return an AppError
     func AppErrorFromJSON(data io.Reader) *AppError {
     	str := ""
    
  • server/public/model/utils_test.go+36 0 modified
    @@ -155,6 +155,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Detailed", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot)
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -166,6 +178,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Detailed + Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -176,6 +200,18 @@ func TestAppErrorSerialize(t *testing.T) {
     
     		require.EqualError(t, berr, aerr.Error())
     	})
    +
    +	t.Run("Detailed + Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
     }
     
     func TestCopyStringMap(t *testing.T) {
    
aa222c66b799

[MM-57070] Remove detailed_error from errors when not in dev mode (#26414) (#26528)

https://github.com/mattermost/mattermostChristopher PoileMar 20, 2024via ghsa
6 files changed · +55 5
  • server/channels/api4/post_test.go+9 0 modified
    @@ -1497,6 +1497,15 @@ func TestPatchPost(t *testing.T) {
     	})
     
     	t.Run("invalid requests", func(t *testing.T) {
    +		var origEnableDeveloper bool
    +		th.App.UpdateConfig(func(cfg *model.Config) {
    +			origEnableDeveloper = *cfg.ServiceSettings.EnableDeveloper
    +			*cfg.ServiceSettings.EnableDeveloper = true
    +		})
    +		defer th.App.UpdateConfig(func(cfg *model.Config) {
    +			*cfg.ServiceSettings.EnableDeveloper = origEnableDeveloper
    +		})
    +
     		r, err := client.DoAPIPut(context.Background(), "/posts/"+post.Id+"/patch", "garbage")
     		require.EqualError(t, err, "Invalid or missing post in request body., invalid character 'g' looking for beginning of value")
     		require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code")
    
  • server/channels/app/platform/websocket_router.go+1 1 modified
    @@ -134,7 +134,7 @@ func returnWebSocketError(ps *PlatformService, conn *WebConn, r *model.WebSocket
     		return
     	}
     
    -	err.DetailedError = ""
    +	err.WipeDetailed()
     	errorResp := model.NewWebSocketError(r.Seq, err)
     	hub.SendMessage(conn, errorResp)
     }
    
  • server/channels/web/handlers.go+2 2 modified
    @@ -376,14 +376,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     
     		// Block out detailed error when not in developer mode
     		if !*c.App.Config().ServiceSettings.EnableDeveloper {
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     		}
     
     		// Sanitize all 5xx error messages in hardened mode
     		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err.StatusCode >= 500 {
     			c.Err.Id = ""
     			c.Err.Message = "Internal Server Error"
    -			c.Err.DetailedError = ""
    +			c.Err.WipeDetailed()
     			c.Err.StatusCode = 500
     			c.Err.Where = ""
     			c.Err.IsOAuth = false
    
  • server/channels/wsapi/websocket_handler.go+2 2 modified
    @@ -41,7 +41,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", sessionErr.SystemMessage(i18n.T)),
     			mlog.Err(sessionErr),
     		)
    -		sessionErr.DetailedError = ""
    +		sessionErr.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, sessionErr)
     		hub.SendMessage(conn, errResp)
     		return
    @@ -63,7 +63,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo
     			mlog.String("error_message", err.SystemMessage(i18n.T)),
     			mlog.Err(err),
     		)
    -		err.DetailedError = ""
    +		err.WipeDetailed()
     		errResp := model.NewWebSocketError(r.Seq, err)
     		hub.SendMessage(conn, errResp)
     		return
    
  • server/public/model/utils.go+5 0 modified
    @@ -336,6 +336,11 @@ func (er *AppError) Wrap(err error) *AppError {
     	return er
     }
     
    +func (er *AppError) WipeDetailed() {
    +	er.wrapped = nil
    +	er.DetailedError = ""
    +}
    +
     // AppErrorFromJSON will decode the input and return an AppError
     func AppErrorFromJSON(data io.Reader) *AppError {
     	str := ""
    
  • server/public/model/utils_test.go+36 0 modified
    @@ -155,6 +155,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Detailed", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot)
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -166,6 +178,18 @@ func TestAppErrorSerialize(t *testing.T) {
     		require.EqualError(t, berr, aerr.Error())
     	})
     
    +	t.Run("Wipe Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
    +
     	t.Run("Detailed + Wrapped", func(t *testing.T) {
     		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
     		js := aerr.ToJSON()
    @@ -176,6 +200,18 @@ func TestAppErrorSerialize(t *testing.T) {
     
     		require.EqualError(t, berr, aerr.Error())
     	})
    +
    +	t.Run("Detailed + Wrapped", func(t *testing.T) {
    +		aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
    +		aerr.WipeDetailed()
    +		js := aerr.ToJSON()
    +		berr := AppErrorFromJSON(strings.NewReader(js))
    +		require.Equal(t, "message", berr.Id)
    +		require.Equal(t, "", berr.DetailedError)
    +		require.Equal(t, http.StatusTeapot, berr.StatusCode)
    +
    +		require.EqualError(t, berr, aerr.Error())
    +	})
     }
     
     func TestCopyStringMap(t *testing.T) {
    

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

7

News mentions

0

No linked articles in our index yet.