Detailed error discloses full file path with dev mode off
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.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/mattermost/mattermost-serverGo | >= 8.1.0, < 8.1.12 | 8.1.12 |
github.com/mattermost/mattermost-serverGo | >= 9.5.0, < 9.5.3 | 9.5.3 |
github.com/mattermost/mattermost-serverGo | >= 9.6.0-rc1, < 9.6.1 | 9.6.1 |
github.com/mattermost/mattermost-serverGo | >= 9.4.0, < 9.4.5 | 9.4.5 |
Affected products
1- Range: 9.6.0
Patches
493738756ff79[MM-57070] Remove detailed_error from errors when not in dev mode (#26414) (#26531)
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)
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)
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)
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- github.com/advisories/GHSA-vx97-8q8q-qgq5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-32046ghsaADVISORY
- github.com/mattermost/mattermost/commit/2a48b5b3428cae494452125401e4f72780543ac8ghsaWEB
- github.com/mattermost/mattermost/commit/93738756ff79777c6e340c8de63a7b4b0f881d27ghsaWEB
- github.com/mattermost/mattermost/commit/aa222c66b799c12e32eeb8eae6f555bf6140375bghsaWEB
- github.com/mattermost/mattermost/commit/c84c25b20c8b8726a2f126ae9370a72498096172ghsaWEB
- mattermost.com/security-updatesghsaWEB
News mentions
0No linked articles in our index yet.