VYPR
Low severityNVD Advisory· Published Mar 20, 2026· Updated Mar 25, 2026

Nhost Storage Affected by MIME Type Spoofing via Trusted Client Content-Type Header in Storage Upload

CVE-2026-33221

Description

Nhost is an open source Firebase alternative with GraphQL. Prior to version 0.12.0, the storage service's file upload handler trusts the client-provided Content-Type header without performing server-side MIME type detection. This allows an attacker to upload files with an arbitrary MIME type, bypassing any MIME-type-based restrictions configured on storage buckets. This issue has been patched in version 0.12.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/nhost/nhostGo
< 0.0.0-20260318074820-c4bd53f042d70.0.0-20260318074820-c4bd53f042d7

Affected products

1

Patches

1
c4bd53f042d7

fix(storage): always detect mimetype when uploading files (#4018)

https://github.com/nhost/nhostDavid BarrosoMar 18, 2026via ghsa
2 files changed · +17 12
  • services/storage/controller/upload_files.go+10 5 modified
    @@ -4,6 +4,7 @@ import (
     	"context"
     	"encoding/json"
     	"fmt"
    +	"io"
     	"log/slog"
     	"mime/multipart"
     	"net/http"
    @@ -53,11 +54,8 @@ func (ctrl *Controller) getMultipartFile(file fileData) (multipart.File, string,
     		)
     	}
     
    -	contentType := file.header.Header.Get("Content-Type")
    -	if contentType != "" && contentType != "application/octet-stream" {
    -		return fileContent, contentType, nil
    -	}
    -
    +	// Always detect MIME type from file content, never trust the client-provided
    +	// Content-Type header to prevent MIME type spoofing (GHSA-g9f6-9775-hffm).
     	mt, err := mimetype.DetectReader(fileContent)
     	if err != nil {
     		return nil, "",
    @@ -66,6 +64,13 @@ func (ctrl *Controller) getMultipartFile(file fileData) (multipart.File, string,
     			)
     	}
     
    +	if _, err := fileContent.Seek(0, io.SeekStart); err != nil {
    +		return nil, "",
    +			InternalServerError(
    +				fmt.Errorf("problem seeking file %s: %w", file.Name, err),
    +			)
    +	}
    +
     	return fileContent, mt.String(), nil
     }
     
    
  • services/storage/controller/upload_files_test.go+7 7 modified
    @@ -132,7 +132,7 @@ func TestUploadFile(t *testing.T) {
     				},
     				{
     					contents:    "more content",
    -					contentType: "text/markdown",
    +					contentType: "image/png",
     					md: fakeFileMetadata{
     						Name:     "another_file.md",
     						ID:       uuid.New().String(),
    @@ -211,15 +211,15 @@ func TestUploadFile(t *testing.T) {
     			}
     
     			{
    -				// file 2
    +				// file 2 - client sends text/markdown but server detects from content
     				file := files[1]
     				metadataStorage.EXPECT().InitializeFile(
     					gomock.Any(),
     					file.md.ID,
     					file.md.Name,
     					int64(len(file.contents)),
     					"blah",
    -					"text/markdown",
    +					"text/plain; charset=utf-8",
     					gomock.Any(),
     				).Return(nil)
     
    @@ -229,7 +229,7 @@ func TestUploadFile(t *testing.T) {
     						file.contents,
     					),
     					file.md.ID,
    -					"text/markdown",
    +					"text/plain; charset=utf-8",
     				).Return("some-etag", nil)
     
     				metadataStorage.EXPECT().PopulateMetadata(
    @@ -240,7 +240,7 @@ func TestUploadFile(t *testing.T) {
     					"blah",
     					"some-etag",
     					true,
    -					"text/markdown",
    +					"text/plain; charset=utf-8",
     					file.md.Metadata,
     					gomock.Any(),
     				).Return(
    @@ -253,7 +253,7 @@ func TestUploadFile(t *testing.T) {
     						CreatedAt:        time.Time{}, // ignored
     						UpdatedAt:        time.Time{}, // ignored
     						IsUploaded:       true,
    -						MimeType:         "text/markdown",
    +						MimeType:         "text/plain; charset=utf-8",
     						UploadedByUserId: new("some-valid-uuid"),
     						Metadata:         new(map[string]any{"some": "metadata"}),
     					},
    @@ -308,7 +308,7 @@ func TestUploadFile(t *testing.T) {
     						CreatedAt:        time.Time{}, // ignored
     						UpdatedAt:        time.Time{}, // ignored
     						IsUploaded:       true,
    -						MimeType:         "text/markdown",
    +						MimeType:         "text/plain; charset=utf-8",
     						UploadedByUserId: new("some-valid-uuid"),
     						Metadata:         new(map[string]any{"some": "metadata"}),
     					},
    

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.