diff --git a/cmd/post-policy_test.go b/cmd/post-policy_test.go index 872982970..957f3342b 100644 --- a/cmd/post-policy_test.go +++ b/cmd/post-policy_test.go @@ -27,6 +27,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "strings" "testing" "time" @@ -114,6 +115,65 @@ func newPostPolicyBytesV2(bucketName, objectKey string, expiration time.Time) [] return []byte(retStr) } +// Wrapper +func TestPostPolicyReservedBucketExploit(t *testing.T) { + ExecObjectLayerTestWithDirs(t, testPostPolicyReservedBucketExploit) +} + +// testPostPolicyReservedBucketExploit is a test for the exploit fixed in PR +// #16849 +func testPostPolicyReservedBucketExploit(obj ObjectLayer, instanceType string, dirs []string, t TestErrHandler) { + if err := newTestConfig(globalMinioDefaultRegion, obj); err != nil { + t.Fatalf("Initializing config.json failed") + } + + // Register the API end points with Erasure/FS object layer. + apiRouter := initTestAPIEndPoints(obj, []string{"PostPolicy"}) + + credentials := globalActiveCred + bucketName := minioMetaBucket + objectName := "config/x" + + // This exploit needs browser to be enabled. + if !globalBrowserEnabled { + globalBrowserEnabled = true + defer func() { globalBrowserEnabled = false }() + } + + // initialize HTTP NewRecorder, this records any mutations to response writer inside the handler. + rec := httptest.NewRecorder() + req, perr := newPostRequestV4("", bucketName, objectName, []byte("pwned"), credentials.AccessKey, credentials.SecretKey) + if perr != nil { + t.Fatalf("Test %s: Failed to create HTTP request for PostPolicyHandler: %v", instanceType, perr) + } + + contentTypeHdr := req.Header.Get("Content-Type") + contentTypeHdr = strings.Replace(contentTypeHdr, "multipart/form-data", "multipart/form-datA", 1) + req.Header.Set("Content-Type", contentTypeHdr) + req.Header.Set("User-Agent", "Mozilla") + + // Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic ofthe handler. + // Call the ServeHTTP to execute the handler. + apiRouter.ServeHTTP(rec, req) + + ctx, cancel := context.WithCancel(GlobalContext) + defer cancel() + + // Now check if we actually wrote to backend (regardless of the response + // returned by the server). + z := obj.(*erasureServerPools) + xl := z.serverPools[0].sets[0] + erasureDisks := xl.getDisks() + parts, errs := readAllFileInfo(ctx, erasureDisks, bucketName, objectName+"/upload.txt", "", false) + for i := range parts { + if errs[i] == nil { + if parts[i].Name == objectName+"/upload.txt" { + t.Errorf("Test %s: Failed to stop post policy handler from writing to minioMetaBucket", instanceType) + } + } + } +} + // Wrapper for calling TestPostPolicyBucketHandler tests for both Erasure multiple disks and single node setup. func TestPostPolicyBucketHandler(t *testing.T) { ExecObjectLayerTest(t, testPostPolicyBucketHandler) diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 6cf3dc172..c3ba383e8 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -1885,21 +1885,29 @@ func ExecObjectLayerTestWithDirs(t TestErrHandler, objTest objTestTypeWithDirs) ctx, cancel := context.WithCancel(context.Background()) defer cancel() + if localMetacacheMgr != nil { + localMetacacheMgr.deleteAll() + } + + initAllSubsystems(ctx) objLayer, fsDirs, err := prepareErasure16(ctx) if err != nil { t.Fatalf("Initialization of object layer failed for Erasure setup: %s", err) } - defer objLayer.Shutdown(ctx) - - // initialize the server and obtain the credentials and root. - // credentials are necessary to sign the HTTP request. - if err = newTestConfig(globalMinioDefaultRegion, objLayer); err != nil { - t.Fatal("Unexpected error", err) - } + setObjectLayer(objLayer) + initConfigSubsystem(ctx, objLayer) + globalIAMSys.Init(ctx, objLayer, globalEtcdClient, 2*time.Second) // Executing the object layer tests for Erasure. objTest(objLayer, ErasureTestStr, fsDirs, t) - defer removeRoots(fsDirs) + + objLayer.Shutdown(context.Background()) + if localMetacacheMgr != nil { + localMetacacheMgr.deleteAll() + } + setObjectLayer(newObjectLayerFn()) + cancel() + removeRoots(fsDirs) } // ExecObjectLayerDiskAlteredTest - executes object layer tests while altering diff --git a/internal/config/identity/ldap/config.go b/internal/config/identity/ldap/config.go index d7aef70a3..84efabe5e 100644 --- a/internal/config/identity/ldap/config.go +++ b/internal/config/identity/ldap/config.go @@ -189,7 +189,7 @@ func Lookup(s config.Config, rootCAs *x509.CertPool) (l Config, err error) { SRVRecordName: getCfgVal(SRVRecordName), } - // Parse explicity enable=on/off flag. If not set, defaults to `true` + // Parse explicitly enable=on/off flag. If not set, defaults to `true` // because ServerAddr is set. if v := getCfgVal(config.Enable); v != "" { l.LDAP.Enabled, err = config.ParseBool(v)