Skip to content

Add an option to disable object sharing and its public proxy #52

Description

@jiri-pejchal

Silo Console lets authenticated users create time-limited links that allow recipients to download an object without signing in. By default, these links use a public Console endpoint that proxies the download from the configured Silo server.

The endpoint checks that the initial URL points to that server, but not that it is a genuine presigned object URL. It can therefore proxy unauthenticated GET requests to other paths on the server. No configuration option disables this behavior without disabling the entire Console UI.

In a deployment running with MINIO_PROMETHEUS_AUTH_TYPE=public, the demonstrated impact is access across a network boundary to internal metrics endpoints. This is not a demonstrated general SSRF. Redirects could broaden the reachable targets, but no anonymous redirect primitive has been demonstrated.

Observed behavior

The route is declared without authentication (security: [],swagger.yml:3200-3204):

/api/v1/download-shared-object/{encoded-url}

decodeMinIOStringURL base64-decodes the supplied URL and compares its host to CONSOLE_MINIO_SERVER. It does not inspect the path, the query string, or the presence of X-Amz-Signature. Endpoints requiring SigV4 still reject the request. The Console relays the body only when the final response is 200 OK. For other responses, it reveals only the upstream status code and status text.

Security-boundary bypass

MINIO_PROMETHEUS_AUTH_TYPE=public removes authentication from the metrics endpoints on the Silo S3 API port. The Console port is reachable externally. The proxy target is the loopback endpoint 127.0.0.1:9000, which is not.
The proxy therefore carries an anonymous external request to an endpoint that is otherwise reachable only from inside the pod.

The encoded path is the base64url form of http://127.0.0.1:9000/minio/metrics/v3/cluster/usage/buckets; adjust the scheme and port to the deployment's CONSOLE_MINIO_SERVER value.

  GET /api/v1/download-shared-object/aHR0cDovLzEyNy4wLjAuMTo5MDAwL21pbmlvL21ldHJpY3MvdjMvY2x1c3Rlci91c2FnZS9idWNrZXRz
  Host: <console-host>
  (no Authorization header, no session cookie)

  HTTP/1.1 200 OK
<Prometheus text exposition: one series per bucket, bucket
  names as label values, with object counts and sizes>

The same method reaches /minio/v2/metrics/cluster, which returns node names, drive count and the quorum and erasure layout.

Why deployment-side mitigation fails

  • Creating a share link through the Console requires authentication, but calling the proxy endpoint does not. Because callers can construct proxy URLs themselves, restricting share-link creation does not prevent anonymous use of the proxy.
  • CONSOLE_SHARE_MINIO_URL controls only the default format of generated share links. An authenticated user can select the other format for an individual link using toggle_url (api/user_objects.go:1074–1078). Neither setting disables or restricts the public proxy endpoint.
  • The supported CONSOLE_* environment variables include no option to disable object sharing or the public proxy (api/consts.go:20–91).
  • MINIO_BROWSER=off disables the entire embedded Console, including its UI. This is not a practical mitigation for deployments that require Console access.

Request

Would you consider a server-side option to disable object sharing? When set, it could reject share-link creation, reject requests to the public proxy, and hide the share controls in the UI.

As defense in depth, the HTTP client should reject redirects or apply the configured-host restriction to every redirect target. Merely requiring presigned-S3 query parameters would not be sufficient: an attacker could attach fake signing parameters to an otherwise public internal endpoint. A stronger design could authenticate the encoded proxy URL itself — for example, with a Console-generated MAC — or retain server-side state for issued share links. Silo would continue to validate the underlying S3 presigned request.

Version tested: Silo RELEASE.2026-09-03T13-18-01Z
Code: decodeMinIOStringURL, api/public_objects.go:45-113. The proxy behavior originates in MinIO Console commit ceee83f — "Use Console as proxy for share object logic" (#3284, April 2024).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions