From 39c5c99c49fe7befd99df63c8bd5426385959181 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Thu, 23 Apr 2026 04:27:26 +0000 Subject: [PATCH 1/2] client: fix nil-part panic in MultipartDeserialize on malformed body MultipartDeserialize() handled r.NextPart() by only checking for io.EOF and otherwise using the returned *Part unconditionally. When the caller declares Content-Type: multipart/related but the body is not valid MIME multipart data (missing/malformed boundary, truncated body, plain text, etc.), NextPart() returns (nil, ). The next line dereferenced nil via part.Header.Get("Content-Type") and panicked the goroutine handling the request. The request path starts unauthenticated (POST /nsmf-pdusession/v1/sm-contexts on SMF and similar MultipartRelatedBinding paths on every NF that uses this library), so any attacker reaching the SBI port can deterministically crash the handling goroutine. Return the NextPart() error to the caller instead of reading nil.Header. Also fix the part.Read() error check that was inverted (compared err to nil when it should return on err != nil and tolerate io.EOF). Refs free5gc/free5gc issue 1026. --- client.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client.go b/client.go index cba9969c..37247d48 100644 --- a/client.go +++ b/client.go @@ -601,17 +601,21 @@ func MultipartDeserialize(b []byte, v interface{}, boundary string) (err error) var part, nextPart *multipart.Part multipartBody := make([]byte, 1400) - // if no remian part, break this loop - if nextPart, err = r.NextPart(); err == io.EOF { + // if no remain part, break this loop; propagate any other error (e.g. malformed + // boundary) rather than continuing with a nil *Part and panicking below. + nextPart, err = r.NextPart() + if err == io.EOF { break - } else { - part = nextPart } + if err != nil { + return fmt.Errorf("multipart NextPart: %w", err) + } + part = nextPart contentType := part.Header.Get("Content-Type") var n int n, err = part.Read(multipartBody) - if err == nil { + if err != nil && err != io.EOF { return err } multipartBody = multipartBody[:n] From 11361a54319876083b366cc2d936217aaedf55fd Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Wed, 6 May 2026 11:55:53 +0000 Subject: [PATCH 2/2] address review: trim inline comments per maintainer feedback Signed-off-by: SAY-5 --- client.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client.go b/client.go index 37247d48..45e12a11 100644 --- a/client.go +++ b/client.go @@ -601,8 +601,7 @@ func MultipartDeserialize(b []byte, v interface{}, boundary string) (err error) var part, nextPart *multipart.Part multipartBody := make([]byte, 1400) - // if no remain part, break this loop; propagate any other error (e.g. malformed - // boundary) rather than continuing with a nil *Part and panicking below. + // if no remain part, break this loop nextPart, err = r.NextPart() if err == io.EOF { break