shieldfy / API-Security-Checklist

Checklist of the most important security countermeasures when designing, testing, and releasing your API
MIT License
22.21k stars 2.57k forks source link

Why "User own resource ID should be avoided. Use /me/orders instead of /user/654321/orders." ? #144

Closed deveasywork closed 1 year ago

deveasywork commented 3 years ago

Is that possible can someone explain why the "User own resource ID should be avoided. Use /me/orders instead of /user/654321/orders." is a security concern?

I agree that user can know your 654321 is your user id then probably loop to try /user/654322/orders etc. However, isn't it the api should check whether the user id has privilege as well? E.g. is 654322 customer of the caller's token user? If yes, he can still view it.

So using pk here is just making it easy to loop and test, but by right the code itself should have checking for privilege too.

If not, using UUID would be insecure too right? I can still loop it, but longer period. And if somehow i know other company customer uuid, I can access it too.

Is there any other point I miss out? Thanks!

spatecon commented 3 years ago

Because, developer can forget do some security check something, and you can easily loop over all orders without additional auth. That what I found in big mobile app a month ago, so I think that's a good tip.

netcode commented 3 years ago

@deveasywork I agree that whether if you make it /me/orders or /user/654321/orders you have to build a strong permission & roles system. But making it me/orders has more advantages.

  1. As @ilya310300 said, some developers can forget to check for authorization specially in big unorganized systems so randomly generated hidden ids seems to be good idea.
  2. Hide the id can save you resources, because script kiddie and random hackers will attempt to abuse the url and brute force It anyway.
  3. make url shorter and less confusing to API consuming part ex. frontend developers ( not a security tip but valid )
deveasywork commented 3 years ago

Noted. Thanks for the explanation.

I agree with /me/orders. How about for a use case like - An API to retrieve profile of an employee from a company. Admin has the right to retrieve other employee profile too, as long as they are in the same company.

Would you suggest /users/1252 ? The API caller can be user with ID 899. This request "/users/1252" is validate with the JWT token of user's 899. And in this API, I did check if user 899 is an admin and 1252 belongs to company of 899.

"Don't auto-increment IDs. Use UUID instead." In this scenario, would you suggest to use UUID in place? I think "/users/123e4567-e89b-12d3-a456-426614174000" doesnt look like a good idea.

Thanks!

spatecon commented 3 years ago

I think "/users/123e4567-e89b-12d3-a456-426614174000" doesnt look like a good idea.

It does :)