浏览代码

Check bucket name and object key in S3, GCS, ABS, and Swift integrations

DarthSim 1 年之前
父节点
当前提交
095f56a5b1
共有 5 个文件被更改,包括 75 次插入6 次删除
  1. 3 0
      CHANGELOG.md
  2. 17 2
      transport/azure/azure.go
  3. 20 2
      transport/gcs/gcs.go
  4. 20 2
      transport/s3/s3.go
  5. 15 0
      transport/swift/swift.go

+ 3 - 0
CHANGELOG.md

@@ -4,6 +4,9 @@
 ### Add
 - Add [IMGPROXY_ALWAYS_RASTERIZE_SVG](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_ALWAYS_RASTERIZE_SVG) config.
 
+### Change
+- Respond with 404 when the bucket/container name or object key is empty in an S3, Google Cloud Storage, Azure Blob Storage, or OpenStack Object Storage (Swift) URL.
+
 ## [3.23.0] - 2024-03-11
 ### Add
 - Add request ID, processing/info options, and source image URL to error reports.

+ 17 - 2
transport/azure/azure.go

@@ -84,7 +84,22 @@ func New() (http.RoundTripper, error) {
 
 func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
 	container := req.URL.Host
-	key := req.URL.Path
+	key := strings.TrimPrefix(req.URL.Path, "/")
+
+	if len(container) == 0 || len(key) == 0 {
+		body := strings.NewReader("Invalid ABS URL: container name or object key is empty")
+		return &http.Response{
+			StatusCode:    http.StatusNotFound,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Header:        http.Header{},
+			ContentLength: int64(body.Len()),
+			Body:          io.NopCloser(body),
+			Close:         false,
+			Request:       req,
+		}, nil
+	}
 
 	statusCode := http.StatusOK
 
@@ -112,7 +127,7 @@ func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
 		statusCode = http.StatusPartialContent
 	}
 
-	result, err := t.client.DownloadStream(req.Context(), container, strings.TrimPrefix(key, "/"), opts)
+	result, err := t.client.DownloadStream(req.Context(), container, key, opts)
 	if err != nil {
 		if azError, ok := err.(*azcore.ResponseError); !ok || azError.StatusCode < 100 || azError.StatusCode == 301 {
 			return nil, err

+ 20 - 2
transport/gcs/gcs.go

@@ -77,8 +77,26 @@ func New() (http.RoundTripper, error) {
 }
 
 func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
-	bkt := t.client.Bucket(req.URL.Host)
-	obj := bkt.Object(strings.TrimPrefix(req.URL.Path, "/"))
+	bucket := req.URL.Host
+	key := strings.TrimPrefix(req.URL.Path, "/")
+
+	if len(bucket) == 0 || len(key) == 0 {
+		body := strings.NewReader("Invalid GCS URL: bucket name or object key is empty")
+		return &http.Response{
+			StatusCode:    http.StatusNotFound,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Header:        http.Header{},
+			ContentLength: int64(body.Len()),
+			Body:          io.NopCloser(body),
+			Close:         false,
+			Request:       req,
+		}, nil
+	}
+
+	bkt := t.client.Bucket(bucket)
+	obj := bkt.Object(key)
 
 	if g, err := strconv.ParseInt(req.URL.RawQuery, 10, 64); err == nil && g > 0 {
 		obj = obj.Generation(g)

+ 20 - 2
transport/s3/s3.go

@@ -94,9 +94,27 @@ func New() (http.RoundTripper, error) {
 }
 
 func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
+	bucket := req.URL.Host
+	key := strings.TrimPrefix(req.URL.Path, "/")
+
+	if len(bucket) == 0 || len(key) == 0 {
+		body := strings.NewReader("Invalid S3 URL: bucket name or object key is empty")
+		return &http.Response{
+			StatusCode:    http.StatusNotFound,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Header:        http.Header{},
+			ContentLength: int64(body.Len()),
+			Body:          io.NopCloser(body),
+			Close:         false,
+			Request:       req,
+		}, nil
+	}
+
 	input := &s3.GetObjectInput{
-		Bucket: aws.String(req.URL.Host),
-		Key:    aws.String(strings.TrimPrefix(req.URL.Path, "/")),
+		Bucket: aws.String(bucket),
+		Key:    aws.String(key),
 	}
 
 	if len(req.URL.RawQuery) > 0 {

+ 15 - 0
transport/swift/swift.go

@@ -54,6 +54,21 @@ func (t transport) RoundTrip(req *http.Request) (resp *http.Response, err error)
 	container := req.URL.Host
 	objectName := strings.TrimPrefix(req.URL.Path, "/")
 
+	if len(container) == 0 || len(objectName) == 0 {
+		body := strings.NewReader("Invalid Swift URL: container name or object name is empty")
+		return &http.Response{
+			StatusCode:    http.StatusNotFound,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Header:        http.Header{},
+			ContentLength: int64(body.Len()),
+			Body:          io.NopCloser(body),
+			Close:         false,
+			Request:       req,
+		}, nil
+	}
+
 	reqHeaders := make(swift.Headers)
 	if r := req.Header.Get("Range"); len(r) > 0 {
 		reqHeaders["Range"] = r