CVE-2026-6340
Description
Mattermost versions 11.5.x <= 11.5.1, 10.11.x <= 10.11.13, 11.4.x <= 11.4.3 fail to validate 7zip archive structure before processing which allows an authenticated attacker to cause server memory exhaustion and denial of service via uploading a specially crafted 7zip file with excessive folder declarations.. Mattermost Advisory ID: MMSA-2026-00573
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Mattermost fails to validate 7zip archive structures, allowing authenticated attackers to cause memory exhaustion via a crafted file.
Vulnerability
Mattermost versions 11.5.x <= 11.5.1, 10.11.x <= 10.11.13, and 11.4.x <= 11.4.3 fail to validate the structure of 7zip archives before processing. This allows an authenticated attacker to upload a specially crafted 7zip file containing excessive folder declarations, leading to server memory exhaustion and denial of service [1].
Exploitation
An attacker must be authenticated to the Mattermost server. The attacker uploads a crafted 7zip archive with an excessive number of folder declarations. The server does not validate the archive structure before attempting to process it, triggering memory exhaustion [1].
Impact
Successful exploitation causes server memory exhaustion, resulting in denial of service for legitimate users. The attack does not lead to data disclosure or remote code execution, but availability is compromised [1].
Mitigation
Mattermost has not yet released a fix for this issue in the affected versions. Users should monitor the Mattermost security updates page for patch announcements and consider disabling 7zip upload functionality if possible as a workaround [1].
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 products
1- Range: 11.5.x <= 11.5.1, 10.11.x <= 10.11.13, 11.4.x <= 11.4.3
Patches
26838381cf9b5[MM-65701] Fix for docextractor archive handling (#34983) (#35792)
2 files changed · +59 −0
server/platform/services/docextractor/archive.go+7 −0 modified@@ -41,6 +41,13 @@ func getExtAlsoTarGz(name string) string { } func (ae *archiveExtractor) Extract(name string, r io.ReadSeeker, maxFileSize int64) (string, error) { + // MM-65701: Skip 7zip files due to OOM vulnerability in bodgit/sevenzip library + match, _ := (archives.SevenZip{}).Match(context.Background(), name, r) + _, _ = r.Seek(0, io.SeekStart) // Reset reader position after Match reads from stream + if match.ByName || match.ByStream { + return "", nil + } + ext := getExtAlsoTarGz(name) // Create a temporary file, using `*` control the random component while preserving the extension.
server/platform/services/docextractor/archive_test.go+52 −0 added@@ -0,0 +1,52 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package docextractor + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestArchiveExtractorSkips7zip(t *testing.T) { + ae := &archiveExtractor{} + + t.Run("7zip file with .7z extension returns empty string", func(t *testing.T) { + // Valid 7zip header (minimal) + sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + result, err := ae.Extract("test.7z", bytes.NewReader(sevenZipData), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip content with wrong extension is still blocked", func(t *testing.T) { + // 7zip content disguised with .zip extension - should still be blocked via stream detection + sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + result, err := ae.Extract("malicious.zip", bytes.NewReader(sevenZipData), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip at offset with .7z extension is blocked via filename", func(t *testing.T) { + junkPrefix := []byte{0x00, 0x00, 0x00, 0x00} + sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + dataWithOffset := append(junkPrefix, sevenZipSig...) + result, err := ae.Extract("test.7z", bytes.NewReader(dataWithOffset), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip at offset with wrong extension fails safely", func(t *testing.T) { + // Edge case: 7zip content at offset with non-.7z extension. + // Our check won't catch it (ByName=false, ByStream=false), but archives.FileSystem + // also won't identify it as 7zip, so it fails to extract rather than triggering OOM. + junkPrefix := []byte{0x00, 0x00, 0x00, 0x00} + sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + dataWithOffset := append(junkPrefix, sevenZipSig...) + _, err := ae.Extract("malicious.zip", bytes.NewReader(dataWithOffset), 0) + assert.Error(t, err) // fails to extract as any valid archive format + }) +}
7c46e1821533[MM-65701] Fix for docextractor archive handling (#34983) (#35790)
2 files changed · +59 −0
server/platform/services/docextractor/archive.go+7 −0 modified@@ -41,6 +41,13 @@ func getExtAlsoTarGz(name string) string { } func (ae *archiveExtractor) Extract(name string, r io.ReadSeeker, maxFileSize int64) (string, error) { + // MM-65701: Skip 7zip files due to OOM vulnerability in bodgit/sevenzip library + match, _ := (archives.SevenZip{}).Match(context.Background(), name, r) + _, _ = r.Seek(0, io.SeekStart) // Reset reader position after Match reads from stream + if match.ByName || match.ByStream { + return "", nil + } + ext := getExtAlsoTarGz(name) // Create a temporary file, using `*` control the random component while preserving the extension.
server/platform/services/docextractor/archive_test.go+52 −0 added@@ -0,0 +1,52 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package docextractor + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestArchiveExtractorSkips7zip(t *testing.T) { + ae := &archiveExtractor{} + + t.Run("7zip file with .7z extension returns empty string", func(t *testing.T) { + // Valid 7zip header (minimal) + sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + result, err := ae.Extract("test.7z", bytes.NewReader(sevenZipData), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip content with wrong extension is still blocked", func(t *testing.T) { + // 7zip content disguised with .zip extension - should still be blocked via stream detection + sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + result, err := ae.Extract("malicious.zip", bytes.NewReader(sevenZipData), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip at offset with .7z extension is blocked via filename", func(t *testing.T) { + junkPrefix := []byte{0x00, 0x00, 0x00, 0x00} + sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + dataWithOffset := append(junkPrefix, sevenZipSig...) + result, err := ae.Extract("test.7z", bytes.NewReader(dataWithOffset), 0) + require.NoError(t, err) + assert.Empty(t, result) + }) + + t.Run("7zip at offset with wrong extension fails safely", func(t *testing.T) { + // Edge case: 7zip content at offset with non-.7z extension. + // Our check won't catch it (ByName=false, ByStream=false), but archives.FileSystem + // also won't identify it as 7zip, so it fails to extract rather than triggering OOM. + junkPrefix := []byte{0x00, 0x00, 0x00, 0x00} + sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00} + dataWithOffset := append(junkPrefix, sevenZipSig...) + _, err := ae.Extract("malicious.zip", bytes.NewReader(dataWithOffset), 0) + assert.Error(t, err) // fails to extract as any valid archive format + }) +}
Vulnerability mechanics
Root cause
"The archive extractor does not validate 7zip archive structure before processing, allowing a crafted 7zip file with excessive folder declarations to trigger unbounded memory allocation in the underlying library."
Attack vector
An authenticated attacker uploads a specially crafted 7zip file containing an excessive number of folder declarations. When Mattermost's document extractor processes the file via the `archiveExtractor.Extract` method, the underlying `bodgit/sevenzip` library allocates memory based on the untrusted folder count without bounds checking [CWE-789]. This leads to server memory exhaustion and denial of service. The attack requires only a low-privilege account and can be carried out over the network.
Affected code
The vulnerable code is in `server/platform/services/docextractor/archive.go` within the `archiveExtractor.Extract` method. The function passes user-supplied archive data directly to the `bodgit/sevenzip` library without first validating whether the file is a 7zip archive, allowing the library to parse malicious folder declarations that cause excessive memory allocation.
What the fix does
The patch adds an early-exit check at the top of `archiveExtractor.Extract` in `archive.go` [patch_id=918566][patch_id=918567]. Before any archive processing begins, the code calls `archives.SevenZip{}.Match()` to detect 7zip content by filename or stream signature. If a match is found, the method returns an empty string immediately, preventing the vulnerable library from ever parsing the malicious archive. The reader position is reset after the match check to avoid corrupting subsequent processing.
Preconditions
- authAttacker must be authenticated to the Mattermost instance
- inputAttacker must upload a specially crafted 7zip file with excessive folder declarations
Generated on May 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1- mattermost.com/security-updatesnvdVendor Advisory
News mentions
0No linked articles in our index yet.