Issue
I'm new in backend, never worked with it before.
I want to add to my app authentication system: client asks server for unique ID, server generates about 5-6 symbols ID and return it to the client. The user can use this ID so others can find his device by it. After some delay (like few hours) server deletes unique ID so client has to ask for another one to continue using server services.
For my app this should be comfortable way - without any oauth systems. But what if someone wants to change client code so the same client will send thousands of requests to the server to create unique ID for it? It sounds really unsafe for server's database, it can be filled with fake IDs of the same device.
My questions are - is it possible to make request for creating ID safer like server checks if exactly this user already asked for ID before to reject this request? Maybe I can check something like client IP / MAC adress or something else? What's best practice for simular problems?
For more detailed context, I'm using Spring, Android SDK, Retrofit. Sorry for english, I'm not native speaker.
Solution
Basically, you are asking if there is a way that the server can identify the client's machine in a way that will work (always or most of the time).
Answer: no there isn't a way to do that.
The best you can get is the (supposed) client IP address that you can get from the Socket
object, HTTPRequest
object or whatever. However, if the client is connecting via a proxy or NAT server or Tor / Onion router, then the IP address will be the IP address of that.
So what is the solution?
Nothing is going to prevent all forms of abuse, but here are some ideas that could help:
You could simply introduce a delay; i.e. wait (say) 5 seconds before responding to each token request. That will limit a single client to (say) 12 tokens a minute which should reduce the number of database entries. (But there are down-sides to this, and a DDOSer could exploit this to their advantage.)
Rate limit based on the (observed) client IP address; e.g. if you see (say) 10 token request in (say) a minute, ignore all further requests from that IP for (say) 10 minutes.
Keep the database entries for a shorter time.
Just use a bigger database. Hundreds or thousands of tokens per second is not a lot if you have gigabytes of database storage. Especially if you are deleting the old entries.
Answered By - Stephen C
Answer Checked By - Katrina (JavaFixing Volunteer)