4

The application I'm working on allows users to create businesses on the map, and upload associated images.

I use Cloud Functions to resize images for various screen resolutions and upload those back to GCS.

To make those images accessible to the public, I generate signed URL which gets saved in the associated entity in Real-time Database.

const [signedUrl] = await bucket.file(path).getSignedUrl({
  action: "read",
  expires: "01-01-2500",
})

Until today, URLs generated as per the code above would allow anyone to view the images. Then suddenly, all of the previously generated URLs became inaccessible and instead show the following error:

<Error>
 <Code>SignatureDoesNotMatch</Code>
 <Message>
   The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
 </Message>
 <StringToSign>
   GET 16725225600 /project-name.appspot.com/placeImage%2F300w%2FUPfppRM1ZyjbwBNiakgzyQ%3D%3D.jpg
 </StringToSign>
</Error>

I see the above message for all of the previously uploaded images. Newly uploaded images can be viewed just fine.

My code closely mimics this example provided by functions-samples, however I'm worried about taking this to production in case the issue becomes a recurring one.

What could be the source of this problem and is there any way to protect ourselves against it in the future?

mpontus
  • 2,143
  • 2
  • 19
  • 21
  • I just experienced the same problem. Did you ever find the root of the problem, or did it never occur again? – Zoon Sep 11 '18 at 17:23
  • It did happen again. I addressed it by adding `predefinedAcl: "publicRead"` to `upload` method options and generating static url like so: `https://storage.googleapis.com/${bucketName}/${path}` – mpontus Sep 11 '18 at 18:26
  • That's a bummer. I'll have my users request fresh downloadUrls through Firebase Storage API for every request. – Zoon Sep 12 '18 at 00:04

1 Answers1

4

It seems this problem is related to the use of v4 URLs.

The behaviour you are experiencing is explained in this comment by the owner of IAM in Google Cloud Functions:

Recently, GCS has already started supporting v4 URLs. For example, [gsutil] generates v4 URLs by default. These URLs have a max expiry of 7 days.

dunxen
  • 73
  • 2
  • 7
  • do you know an alternative to signedURL() function – Hady Rashwan Nov 16 '18 at 17:13
  • @HadyRashwan The only alternative would be to use getDownloadURL() on the client side with Firebase Storage. You’ll need to properly configure your Storage Rules to allow read access for authenticated users. If you need role based access with Security Rules, then I suggest taking a look at Custom Claims. – dunxen Nov 17 '18 at 13:10
  • I've answered an alternative to signedURL, using makePublic: https://stackoverflow.com/a/58016766/2713242 – ersin-ertan Sep 19 '19 at 18:22