For example, if I have a product model, it is good enough to use /products/:id as the URL security-wise? Or do I need to create a special identifier for the URL like a slug?
Also, are there any special considerations for hashed IDs (as in MongoDB) over auto-incremented IDs (as in MySQL) for showing in the URL?
Hi, As Josh Montgomery pointed out its not necessary unless its something very sensitive that said its not a suitable way to expose those id's in auto-incremented way. If someone were to scrape the site, it will be easier to do that, its better to keep a random hash for everything unless extremely necessary.
just dont keep the
:id
as auto-inremented replace it with its random hash or something
if you have highly sensitive data, then I would do what I could to avoid using that model. However, it looks like it could be for some kind of shopping site, then I don't think it's a huge deal. For better security, always sanitize your data from form postings and/or query string variables, that way you have complete control over those public pieces of data.
I don't think there is any problem as such. If exposing your ID makes your database vulnerable then its not the problem with exposing IDs but the insecurity of your database.
Consider Facebook's open graph database publicly available for people to access it (at least earlier). Suppose you can access user data through _id via OAuth, yet you'll not be able access sensitive information about that user. So the point is, exposing IDs in the URL is not a bad approach but how you mask the sensitive data is important.
With respect to URL representation, follow any rule, be it hashed ID with lookup or actual entity IDs but make sure the logic is consistent across the codebase or at least use-case basis so that it's easy to maintain. And, One of answers mentioned about SEO and UX, probably true in-case of client web URLs but I'm not sure if the same is applicable for backend URLs
Actually it's okay. Cause it shouldn't be the determinant for security on your web app.
I once edited the link of a DM with someone on Twitter through the browser's address bar. I saw the ID of the DM and tried incrementing it, which worked!
But I've never heard of Twitter being hacked in any way.
Data on your service should have permission restrictions based on authenticated users. It's called authorization!
Revealing your database ids by itself does not make your site insecure. And hiding them does not automatically make it secure.
But there are people and companies that decouple database ids from public identifiers as part of defence in depth.
It'll be a little harder for an attacker to get to related entities. E.g. in a list selection, you might communicate the index of the option chosen, instead of the identifier, so that it's not even possible to submit an option that wasn't in the list (the alternative is to let them be submitted but invalidate them on the server, which is also safe).
Aside from security, it is good encapsulation. Database ids should probably be considered an implementation detail that shouldn't be exposed to users. You may want to change them when moving database server or something. Or you may not want to show how many orders you've had, if order numbers auto-increment.
Considering user experience (and maybe SEO), a meaningful slug will be better than an arbitrary number. But you could do both to combine ease and UX.
That said, it causes extra work and perhaps extra queries, and might encourage bad practices like leaving search results in memory between requests. If you do proper input validation and keep yours ids stable (even when moving database), you can have a functional and secure site while exposing ids.
What I personally tend to do, based on my opinion and not on any kind of research, is to do a simple bijective encoding of ids. This:
Note that this addresses the user experience and ease, but doesn't help security, and I still have to keep my database ids stable.