minio / minio-js

MinIO Client SDK for Javascript
https://docs.min.io/docs/javascript-client-quickstart-guide.html
Apache License 2.0
964 stars 283 forks source link

SignatureDoesNotMatch when using response-content-disposition with presignedGetObject #820

Open Menci opened 4 years ago

Menci commented 4 years ago

Create a local MinIO server with a testfile in a testbucket.

const MinIO = require("minio");
const client = new MinIO.Client({
        endPoint: "127.0.0.1",
        port: 9000,
        useSSL: false,
        accessKey: "minioadmin",
        secretKey: "minioadmin"
});

(async () => {
        // SignatureDoesNotMatch
        console.log(await client.presignedGetObject("testbucket", "testfile", 60 * 60 * 24, {
                "response-content-disposition": "attachment; filename*=UTF-8''test.png"
        }));

        // Works
        console.log(await client.presignedGetObject("testbucket", "testfile", 60 * 60 * 24, {
                "response-content-disposition": "attachment; filename=UTF-8test.png"
        }));
})();

The first content-disposition is correct according to RFC 5987. But generated link returns a SignatureDoesNotMatch error. The second is removing some special characters from the first, its link is downloadable.

kannappanr commented 4 years ago

@Menci Thanks for filing the issue, we will take a look

Menci commented 4 years ago

Here is a workaround. The filename works on Chrome, but it's non-standard:

return await this.minioClient.presignedGetObject(
  this.configService.config.fileStorage.bucket,
  uuid,
  FILE_DOWNLOAD_EXPIRE_TIME,
  {
    "response-content-disposition": "attachment; filename=\"" + encodeRFC5987ValueChars(filename) + "\""
  }
);
lksnmnn commented 3 years ago

I am getting this error too with filenames containing brackets ( ). The work around does not work on Mac Safari, as Safari will not decode the filename correctly.

Is this issue within minio-js or Minio server? Edit: https://github.com/minio/minio/issues/8897 might be related and suggests it is a client side problem.

prakashsvmx commented 3 years ago

https://github.com/minio/minio-js/pull/959 did you try ?

lksnmnn commented 3 years ago

Just tried it. It still can't match the signature.

Test filename: f().png Header added to presignedGetObject

{
  "response-content-disposition": `attachment; filename=${filename}`,
}

It also does not work with filename*=UTF-8''${filename}

lksnmnn commented 3 years ago

I believe there might be a difference on how JS and Go (?) encode URLs. I.e. JS does not encode () when using encodeURIComponent, but Go does. Anyway, even if I encode it manually, I still have the problem, that Safari does not care. So actually minio server would need to not encode these non-reserverd characters ?!