mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
web: Validate if bucket names are reserved (#3841)
Both '.minio.sys' and 'minio' should be never allowed to be created from web-ui and then fail to list it by filtering them out. Fixes #3840
This commit is contained in:
parent
cddc684559
commit
e5d4e7aa9d
@ -20,7 +20,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -161,17 +160,17 @@ func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Adds verification for incoming paths.
|
// Adds verification for incoming paths.
|
||||||
type minioPrivateBucketHandler struct {
|
type minioPrivateBucketHandler struct {
|
||||||
handler http.Handler
|
handler http.Handler
|
||||||
reservedBucketPath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPrivateBucketHandler(h http.Handler) http.Handler {
|
func setPrivateBucketHandler(h http.Handler) http.Handler {
|
||||||
return minioPrivateBucketHandler{h, minioReservedBucketPath}
|
return minioPrivateBucketHandler{h}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// For all non browser requests, reject access to 'reservedBucketPath'.
|
// For all non browser requests, reject access to 'minioReservedBucketPath'.
|
||||||
if !guessIsBrowserReq(r) && path.Clean(r.URL.Path) == h.reservedBucketPath {
|
bucketName, _ := urlPath2BucketObjectName(r.URL)
|
||||||
|
if !guessIsBrowserReq(r) && isMinioReservedBucket(bucketName) && isMinioMetaBucket(bucketName) {
|
||||||
writeErrorResponse(w, ErrAllAccessDisabled, r.URL)
|
writeErrorResponse(w, ErrAllAccessDisabled, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,17 @@ func isReservedOrInvalidBucket(bucketEntry string) bool {
|
|||||||
if !IsValidBucketName(bucketEntry) {
|
if !IsValidBucketName(bucketEntry) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return bucketEntry == minioMetaBucket || bucketEntry == minioReservedBucket
|
return isMinioMetaBucket(bucketEntry) || isMinioReservedBucket(bucketEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if input bucket is a reserved minio meta bucket '.minio.sys'.
|
||||||
|
func isMinioMetaBucket(bucketName string) bool {
|
||||||
|
return bucketName == minioMetaBucket
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if input bucket is a reserved minio bucket 'minio'.
|
||||||
|
func isMinioReservedBucket(bucketName string) bool {
|
||||||
|
return bucketName == minioReservedBucket
|
||||||
}
|
}
|
||||||
|
|
||||||
// byBucketName is a collection satisfying sort.Interface.
|
// byBucketName is a collection satisfying sort.Interface.
|
||||||
|
@ -50,3 +50,7 @@ var errServerVersionMismatch = errors.New("Server versions do not match")
|
|||||||
|
|
||||||
// errServerTimeMismatch - server times are too far apart.
|
// errServerTimeMismatch - server times are too far apart.
|
||||||
var errServerTimeMismatch = errors.New("Server times are too far apart")
|
var errServerTimeMismatch = errors.New("Server times are too far apart")
|
||||||
|
|
||||||
|
// errReservedBucket - bucket name is reserved for Minio, usually
|
||||||
|
// returned for 'minio', '.minio.sys'
|
||||||
|
var errReservedBucket = errors.New("All access to this bucket is disabled")
|
||||||
|
@ -113,7 +113,7 @@ type MakeBucketArgs struct {
|
|||||||
BucketName string `json:"bucketName"`
|
BucketName string `json:"bucketName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeBucket - make a bucket.
|
// MakeBucket - creates a new bucket.
|
||||||
func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *WebGenericRep) error {
|
func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *WebGenericRep) error {
|
||||||
objectAPI := web.ObjectAPI()
|
objectAPI := web.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
@ -122,12 +122,19 @@ func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, rep
|
|||||||
if !isHTTPRequestValid(r) {
|
if !isHTTPRequestValid(r) {
|
||||||
return toJSONError(errAuthentication)
|
return toJSONError(errAuthentication)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if bucket is a reserved bucket name.
|
||||||
|
if isMinioMetaBucket(args.BucketName) || isMinioReservedBucket(args.BucketName) {
|
||||||
|
return toJSONError(errReservedBucket)
|
||||||
|
}
|
||||||
|
|
||||||
bucketLock := globalNSMutex.NewNSLock(args.BucketName, "")
|
bucketLock := globalNSMutex.NewNSLock(args.BucketName, "")
|
||||||
bucketLock.Lock()
|
bucketLock.Lock()
|
||||||
defer bucketLock.Unlock()
|
defer bucketLock.Unlock()
|
||||||
if err := objectAPI.MakeBucket(args.BucketName); err != nil {
|
if err := objectAPI.MakeBucket(args.BucketName); err != nil {
|
||||||
return toJSONError(err, args.BucketName)
|
return toJSONError(err, args.BucketName)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.UIVersion = browser.UIVersion
|
reply.UIVersion = browser.UIVersion
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -890,6 +897,13 @@ func toJSONError(err error, params ...string) (jerr *json2.Error) {
|
|||||||
Message: apiErr.Description,
|
Message: apiErr.Description,
|
||||||
}
|
}
|
||||||
switch apiErr.Code {
|
switch apiErr.Code {
|
||||||
|
// Reserved bucket name provided.
|
||||||
|
case "AllAccessDisabled":
|
||||||
|
if len(params) > 0 {
|
||||||
|
jerr = &json2.Error{
|
||||||
|
Message: fmt.Sprintf("All access to this bucket %s has been disabled.", params[0]),
|
||||||
|
}
|
||||||
|
}
|
||||||
// Bucket name invalid with custom error message.
|
// Bucket name invalid with custom error message.
|
||||||
case "InvalidBucketName":
|
case "InvalidBucketName":
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
@ -961,6 +975,12 @@ func toWebAPIError(err error) APIError {
|
|||||||
HTTPStatusCode: http.StatusMethodNotAllowed,
|
HTTPStatusCode: http.StatusMethodNotAllowed,
|
||||||
Description: err.Error(),
|
Description: err.Error(),
|
||||||
}
|
}
|
||||||
|
} else if err == errReservedBucket {
|
||||||
|
return APIError{
|
||||||
|
Code: "AllAccessDisabled",
|
||||||
|
HTTPStatusCode: http.StatusForbidden,
|
||||||
|
Description: err.Error(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Convert error type to api error code.
|
// Convert error type to api error code.
|
||||||
var apiErrCode APIErrorCode
|
var apiErrCode APIErrorCode
|
||||||
|
@ -265,6 +265,8 @@ func testMakeBucketWebHandler(obj ObjectLayer, instanceType string, t TestErrHan
|
|||||||
{"", false},
|
{"", false},
|
||||||
{".", false},
|
{".", false},
|
||||||
{"ab", false},
|
{"ab", false},
|
||||||
|
{"minio", false},
|
||||||
|
{".minio.sys", false},
|
||||||
{bucketName, true},
|
{bucketName, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user