0
votes

I create SAS tokens on the server on demand and send them to users so that they can upload blobs. By default, each token is set to expire in an hour. I'm also using Azure Functions for server-side processing.

var cloudStorageAccount = // create a new CloudStorageAccount
var sharedAccessAccountPolicy = new SharedAccessAccountPolicy
{
    Permissions = SharedAccessAccountPermissions.Read | SharedAccessAccountPermissions.Write,
    Services = SharedAccessAccountServices.Blob,
    ResourceTypes = SharedAccessAccountResourceTypes.Object,
    SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
    Protocols = SharedAccessProtocol.HttpsOnly
};

var token = cloudStorageAccount.GetSharedAccessSignature(sharedAccessAccountPolicy);

What I'd like to do is to expire a SAS token once it's been successfully used once by listening to blob changes via EventGridTrigger. For example, if it took the user 10 minutes to upload a file, that token should no longer be usable. This is to prevent abuse because the API that generates SAS tokens is rate limited. If I want the user to upload only one file in an hour, I need a way to enforce this. Somebody with a fast internet connection can theoretically upload dozens of files if the token expires in an hour.

So, my question would be, is it possible to programmatically expire a token even if its expiry date has not been reached? Another alternative that would work in my scenario is to generate one-time tokens if it's possible.

2
If the users are uploading files to a specified container, then in this case, you can use stored access policy to control the expire time dynamically.Ivan Yang

2 Answers

0
votes

You cannot revoke a SAS token before it's expiration data unless it's associated with a Security policy and you revoke that policy or you change the Access Key associated with the storage account. I don't think either of these ideas really applies to your case. SAS tokens are essentially self-contained and cannot be altered once issued, so you cannot expire them early.

See the Revocation section on this page for the official explanation: https://docs.microsoft.com/en-us/azure/storage/blobs/security-recommendations#revocation

"A service SAS that is not associated with a stored access policy cannot be revoked."

Also, there are no one-time use SAS tokens and according to this feedback request, Microsoft has no plans to implement that feature: https://feedback.azure.com/forums/217298-storage/suggestions/6070592-one-time-use-sas-tokens

Your best bet is to simply keep the expiration time as short as possible for your use case. If you absolutely must limit uploads for a specific user, then you consider having the user go through a separate controlled app instead of directly to storage (like a Web API) that can be used as a gatekeeper (checking previous uploads and implementing limit logic).

0
votes

I believe you can use a user delegation SAS for this. A user delegation SAS can be created and revoked programmatically.

https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas

Revoke the user delegation key

You can revoke the user delegation key by calling the Revoke User Delegation Keys operation. When you revoke the user delegation key, any shared access signatures relying on that key become invalid. You can then call the Get User Delegation Key operation again and use the key to create new shared access signatures. This approach is the quickest way to revoke a user delegation SAS.