gaul / s3proxy

Access other storage backends via the S3 API
Apache License 2.0
1.79k stars 233 forks source link

Unsigned URL query parameters broken #688

Open benjaminhr opened 2 months ago

benjaminhr commented 2 months ago

Context

I'm running S3Proxy with azure blob storage. I can create an unsigned URL with an expiry, however I can download the file after the expiry time. This is because S3Proxy simply does a GET request to azure without the signing related query parameters.

Setup docker-compose.yml:

services:
  s3proxy:
    image: andrewgaul/s3proxy
    restart: unless-stopped
    ports:
      - 8080:8080
    environment:
      LOG_LEVEL: "DEBUG"
      LOG_APPENDER: "console"

      S3PROXY_AUTHORIZATION: "none"
      S3PROXY_ENDPOINT: "http://0.0.0.0:8080"
      S3PROXY_IGNORE_UNKNOWN_HEADERS: "true"

      JCLOUDS_PROVIDER: "azureblob"
      JCLOUDS_AZUREBLOB_AUTH: "azureKey"
      JCLOUDS_ENDPOINT: "https://${storage_account_name}.blob.core.windows.net"
      JCLOUDS_IDENTITY: ${storage_account_name}
      JCLOUDS_CREDENTIAL: ${storage_account_key}

With the following code I'm able to produce the unsigned url:

const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");

const getObjectCommand = new GetObjectCommand({
  Bucket: "beerbucket",
  Key: "beer",
});

const url = await getSignedUrl(s3Client, getObjectCommand, {
  expiresIn: 15, // seconds
});

console.log(url);
http://localhost:8080/beerbucket/beer.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=accountName%2F20240916%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240916T142040Z&X-Amz-Expires=15&X-Amz-Signature=6ef5b636ad55aa677ff86d5dfadf6997436ee64316a20be507dc6e05d327935c&X-Amz-SignedHeaders=host&x-id=GetObject

Going to the link, S3Proxy logs show that the request gets translated to GET https://<storage_account_name>.blob.core.windows.net/beerbucket/beer.txt HTTP/1.1 and the expiry is not respected.