Why you shouldn't expose your incrementing IDs

March 7, 2021
English

By default, every Laravel model has an incrementing ID. Although this makes things very easy, there are some security reasons why you shouldn't be exposing this ID to your users. In this article, I'm going to explain why.

Security risk

If you use default incrementing IDs in your URLs, anyone can guess which one is the previous, and which one is the next. For example, you've got orders and you use this URL scheme:

Anyone can know that the previous was 8 and the next will be 10. Of course, you don't want your users to know what others bought.

Although you should return a 403 error if an unauthorized user tries to visit http://www.example.org/orders/8, if you forget to do so you have a big security risk.

Resource harvesting

If you have images and corresponding records in your DB, you can have image names like those:

And anyone can visit http://example.org/images/avatar33.jpg and so on to get all your images. This practice is called resource harvesting and applies to models too but is a bigger problem with static files.

Others know how big your website is

If someone registers and visits their account page, they may end up with a URL like this one:

Now they know they are number 223. This may not seem like an issue at first, but your competition can create an account too and see how many users you have.

Of course, if you create a forum thread or something else with the same URL scheme, you have this problem too. For example:

Solutions

Fortunately, there are plenty of solutions available for this problem. I've described two.

Slugs

You may use slugs to have a unique identifier that exposes nothing about your DB size.

And it is what I do with my blog too. But for some models, a slug doesn't make much sense, such as for users or reviews.

And besides, it's a lot of work to get slugs working, especially if everyone can create a new model. For example:

• What if two slugs are the same?
• What if a title changes?

UUIDs

A UUID (Universally Unique Identifier) is kind of a normal ID, except no-one knows what the previous or next one is.

This is an example of a UUID:

And you'll get URLs like this one: