I have numeric IDs that I would like to use in filenames. So for example with IDs 1, 2, 3 we would have 1.jpg, 2.jpg, and 3.jpg

Now the problem is that clearly a user could just guess 4.jpg and view something they shouldn't be able to find.

Previously we have used UUIDs for this purpose but in this particular case I thought we could use a keyed hash function to avoid having to save a second ID. So 1, 2, and 3 would generate <long value 1>.jpg, <long value 2>.jpg, and <long value 3>.jpg.

So the requirements are:

  1. Given any particular ID, our server can quickly generate the value for the filename
  2. The same ID will generate the same value regardless of when/how many times it is generated (This seems to imply to me that we can't use e.g. AES encryption with an IV, since the IV is supposed to vary each time, or a salted hash function since the value would change when the salt changes)
  3. An attacker cannot guess the values, even if they know an ID

It doesn't matter if, given the value, an attacker can derive the original ID. E.g. they can't find the URL for ID "4" even if they can see the generated values for "1", "2", and "3".

Is there a security concern in using a keyed hash function (HMAC) in this way?

2 Answers 2


No security concern

For hmac it’s all about keeping the key secret - downsides are difficulty in rotating the key (in this use case). If you need the url to be a permanent link then you can’t rotate the key. If the key is compromised you can’t rotate without revoking all the old urls.

But how will you know what file they are trying to access?

the hmac string from hmac(key, fileid) is one way. You can’t take the hmac string and figure out the file ID.

Well, you can, but it’s not very efficient. You’d need to iterate through all possible fileid’s to find the match.

Better may be to sign the url. Http://example.com/file1.jpg/hmac-string. It doesn’t solve key rotation and permanent links but might not matter and that wasn’t in your spec.

  • Yeah - the links need to be permanent, so if someone finds the key then they could generate the URL for any ID. I think that's acceptable though because if we were using random UUIDs we'd be storing them in a database, and if that database got compromised then someone could derive all the URLs.
    – Zout
    Jul 12, 2021 at 16:02

Security concerns? It depends on the goals of your system and on the threats you consider.

For instance, if you you want to provide links only to the users who paid for them, then users can share the links. You have no way to know if particular request comes from the user that has paid for the link.

Also if users store your links unprotected, or the links via unprotected channel, the links can be observed, e.g. in some logs, and thus also other parties will be able to use your links.

Briefly: In your approach you cannot restrict access to particular users only.

If you don't have similar logic, fine. Otherwise these are really security concerns.

  • Users sharing the links is not a concern - in fact them being able to share their own links is a benefit. The only security concern is preventing someone from finding another user's links - sounds like the HMAC approach is fine in this case!
    – Zout
    Jul 12, 2021 at 17:48
  • If sharing the links is a benefit, why do you want prevent users from accessing files?
    – mentallurg
    Jul 12, 2021 at 17:52
  • Not sure where I said I wanted to stop users from accessing them - it's just to stop someone from finding files just by guessing at IDs. If they are given the link it's fine for them to access it.
    – Zout
    Jul 12, 2021 at 18:26
  • Suppose, all users, or many of them, decide to share the links by publishing them at some web site. So anyone will know all the links, or the most of them. What is then the purpose in preventing the users from guessing links?
    – mentallurg
    Jul 12, 2021 at 22:20
  • Think of it like Google Photos: you can share links to your personal photos and anyone can view them, but nobody can guess the links. If the url pattern was just an incrementing number like 1.jpg 2.jpg 3.jpg I could easily type in 50.jpg and be guaranteed to see someone's photo.
    – Zout
    Jul 13, 2021 at 13:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .