I have a service, offering a physical good in exchange for either money or via code given out by us. The service is accessed through a mobile application.
The codes have usage restrictions, for example to be only used once per user. This is achieved by sending a unique identifier with the request to check if the user is allowed to use the code, or not.
This solution obviously only works in the perfect world, where nobody reverse engineers your API.
What I want to prevent is, that a malicious user reverse engineers our publicly facing API, and orders a huge amount of goods severely hurting the business.
The current system has prevents this by having several checks in place:
- unique ID per user, generated on the device (bypass: generated a random UUID on each malicious request)
- rate limiting, a single IP is only allowed to sent X requests per Y minutes (bypass: since the IP acquired through HTTP headers, this should be pretty easy to spoof as well, and will obviously only step in after there is already some considerably amount of damage done)
How can I make sure this is not abused?
The only two solutions I could've come up with are:
- never do full discounts, only do partial discounts (like 50% off), which would require the attacker to still pay for each good, lowering the incentive.
- having accounts, which would require more steps, also lowering the incentive.
And to be honest, I don't want to do either of those.
The unique identifier is generated on the device, on iOS the IDFA is used, on Android the
ANDROID_ID. They're sent as plaintext over HTTPS to the server, to identify the user. If a malicious user wants to replay the request for ordering the goods, he only has to change this identifier and the server will happily accept it as a new order.