10

Question 1

I have a login API endpoint

http://127.0.0.1:8080/api/account/login

It checks if the phone number has been validated. If not it will call

POST http://127.0.0.1:8080/api/account/sendsms  country_code=1, phone_number=1234567

How can I prevent abuse to requesting sms? (It'll cost money on my part. I also have throttle function)
I only want sms to be sent if /login failed (at this point email has been validated)
The way I do is to send a custom header X-TOKEN-SMS which acts like an authorization header with jwt token. X-TOKEN-SMS jwt token is created at /login if phone number is not validated = True.
When /sendsms decodes the jwt without error, proceed with requesting sms. If jwt decodes with error then the front-end will redirect to /login.

Is this method a good practice?
How do you allow an API endpoint to be accessed only if some endpoint has been accessed?

Question 2

Let's say I have an endpoint that can only be accessed by an authorized user

http://127.0.0.1:8080/api/account/points

The user can GET points(retrieve all of his/her points) POST points (create a new point) or PATCH (update a point)

How can I prevent an authorized user from abusing the POST /points? They might add points as they please, which is not what my app want it to be. Adding points should be handled by the app logic.

If adding point should not be consumed by REST API, then create a new row directly to the db is more secure?

I found a similar question asked before Secure Rest api from authenticated user But couldn't seem to understand it.

1
  • I'm not sure why you just wouldn't have the login endpoint trigger the SMS without requiring the caller to trigger the SMS.
    – Andy
    Commented Nov 18, 2016 at 0:58

2 Answers 2

3

For the first question, your approach seems correct to me. You consume a token in the sendsms entry that can only be generated by the login endpoint. You could also use a generic token created by login, and not easily guessable (it would be equivalent to a cryptographically generated session ID), used as primary key to a database tuple. There you can store whatever you want (for example the number of SMS still allowed to be sent).

You can also store the "state" in a variable and protect it using, say, HMAC, continuously exchanging it between the server and the client, but you still require some server state to defend against replay attacks on non-idempotent endpoints; at minimum, you need a per-session incremental counter.

The second problem is trickier, and you need first to ask yourself what the difference in behaviour (as seen by the server) would be between the app with its logic, and a malicious user sending repeated requests. You might enforce a minimum delay between requests that is comparable to the maximum rate at which the app can be driven, so that there's no longer an advantage in using tricks rather than going through the app.

3

Here's a problem with your proposed approach. If you send the requests over HTTP, a 3rd-party can snoop the traffic and pick out the authorization token. Then they could send their own requests to the end-point using the token.

Solution: use HTTPS rather than HTTP when doing the initial authorization to obtain the token, and whenever you use the token.

For your second question, the problem is basically intractable. I assume that these "points" are something that should only be changed according to some rules that you have set out. Unless the rules are such you can detect cheats from the server side you are stuck. The only way to solve that is to implement everything that is directly or indirectly involved with scoring on the server side. That probably defeats the purpose of your game.


I note that you are using 127.0.0.1. I'm guessing it is just a placeholder for the real IP address.

But if not, be aware that you are talking to a service running on the user's own computer / device. If the user has physical access and sufficient time / expertise, he / she can most likely subvert any access controls you implement in the service.

The same applies to any client-side logic aimed at enforcing rules or preventing cheating.

(Have you ever wondered why MMOs and the like have problems with cheats? It is not because the vendors don't try. It is because it is impossible to defeat the cheats in software if the cheats control the client-side platform where the software runs.)

1
  • both of you have good answers. However I must choose only one. Thank you. Commented May 5, 2016 at 0:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.