mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-10-10 03:39:05 +02:00
fix: limit LDAP profile picture downloads to 2 MB
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
@@ -756,8 +757,15 @@ func (s *Service) saveProfilePicture(parentCtx context.Context, userId string, p
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
data, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
const maxProfilePictureSize int64 = 2 * 1024 * 1024 // 2MB
|
||||
if res.ContentLength > maxProfilePictureSize {
|
||||
return fmt.Errorf("profile picture must not exceed 2 MB")
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(utils.NewLimitReader(res.Body, maxProfilePictureSize+1))
|
||||
if errors.Is(err, utils.ErrSizeExceeded) {
|
||||
return fmt.Errorf("profile picture must not exceed 2 MB")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to read profile picture: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package ldapsync
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
@@ -45,6 +47,37 @@ func (c *fakeLDAPClient) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSaveProfilePictureRejectsOversizedDownload(t *testing.T) {
|
||||
oversized := bytes.Repeat([]byte{0}, 2*1024*1024+1)
|
||||
|
||||
// Cover both a declared Content-Length and a chunked response that hides its size until it is read
|
||||
tests := []struct {
|
||||
name string
|
||||
chunked bool
|
||||
}{
|
||||
{name: "content length", chunked: false},
|
||||
{name: "chunked", chunked: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
if tt.chunked {
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
_, _ = w.Write(oversized)
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
svc := newService(Dependencies{HTTPClient: server.Client()})
|
||||
|
||||
err := svc.saveProfilePicture(t.Context(), "user-id", server.URL+"/picture.png")
|
||||
|
||||
require.ErrorContains(t, err, "must not exceed 2 MB")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLdapServiceSyncAllReconcilesUsersAndGroups(t *testing.T) {
|
||||
service, db := newTestLdapService(t, newFakeLDAPClient(
|
||||
ldapSearchResult(
|
||||
|
||||
Reference in New Issue
Block a user