TransWikia.com

How to secure my PHP url endpoints

Information Security Asked on November 6, 2021

I have a backend that I developed on PHP/MySql which will provide some URL endpoints in order to get data or post data. I am using those URL endpoints in my application (WebGL application). Now, the problem is, the URL endpoints are public and anyone can use those URL by simply inspecting the browser. An attacker can get the URL endpoints and may post spam data or hang my server etc. So my question is that how do I save my URL endpoints? Remember there is no login option into my application. The WebGL application is public, anyone can view it. I want to use my URLendpoint form the application only.

One Answer

An attacker can get the url endpoints and may post spam data

Do you have some means of telling an attacker from a legitimate user?

(Rate of posting, content of post, etc.). Imagine being the server app, and you see a request coming in. Can you tell whether it is legitimate or not?

If yes, then use them - move that reasoning into your application logic. Better still, add this information to your question so you might get further suggestions and insights.

If not, then unfortunately your answer is "You cannot secure your URL endpoints" (because "secure" implies "distinguish between good and bad guys") and you need to look into things like logins, cookies and/or client certificates.

authenticating an application

You need to add something to the application that an attacker can't easily replicate. This requires making assumptions against what an attacker can and can't do.

No one can defend against an omnipotent attacker. So, you cannot say "I want to defend against anyone". You can only defend against someone that cannot do something that your application can.

So, if the attacker has full access to your application source code and secrets, and therefore can learn to do whatever your application can, again you cannot defend against them.

In Android and iOS, there are "secret areas" that you can interface with, and allow doing something an attacker can't. Basically you establish a secret in the protected area, then ask whoever connects to prove they know the secret. This too is imperfect because you're only authenticating the device, not the application.

If the attacker does not have access to the source code, then you can use a classic challenge/response scheme, where the application contains (either the same for all clients or one assigned to each client) a secret string. All calls are GETs for clarity:

The app has a secret and it is "001:MySecret001".

App --> "application/login?auth=001"  --> server
          <--- "tell me the answer to: 2020-07-21-13:36:35-Qa9XtFtp"

App retrieves its secret, it is "MySecret001", calculates the hash
   of the string "MySecret001,2020-07-21-13:36:35-Qa9XtFtp"
   and sees that it is `57703859adcdb4239e513dd7fe991afe`. So...

App --> "application/login?auth=001&challenge= 2020-07-21-13:36:35Qa9XtFtp&response=57703859adcdb4239e513dd7fe991afe"

The server verifies that the response is indeed the hash of the challenge, and that the challenge timestamp is not too old. Then it retrieves the secret for user 001, and sees it is MySecret001. It does the same calculation the client did. If the two hashes are the same, the client is legitimate.

This, as I said, requires that the attacker cannot crack the app and see what the secret is and how it is manipulated.

The login/password scheme is identical, except that login and password are in the head of the user.

authenticating a request

We still (see above) need that the attacker cannot see the application source code. When this is the case, you can modify (maybe using a filter, which is possible with e.g. jQuery) the request, adding a header or an extra variable:

  • suppose the request is "cmd=add&text=HelloHello&subj=HelloWorld"
  • you sort the request dictionary in alphabetic order:
    • cmd = add
    • subj = HelloWorld
    • text = HelloHello
  • you take the secret, or a random string the server sent the application on the first request (called "nonce") and initialize "hash" to this value
  • for all elements in request:
    • hash = MD5(MD5(hash + key) + value)
  • you add "hash=(whatever)" to your request.

The server receives a request, saves "hash", knows the secret shared with that client, and can therefore repeat the calculation and see whether the hash value matches.

An attacker that does not know the initial "secret" value now cannot send arbitrary commands, because they don't know the appropriate value of the hash for that particular command.

Answered by LSerni on November 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP