Protect script from bots and unwanted requests sending data

I am modifying an android application that uses webapp through webview. Currently, the codebase for webapp is written in ColdFusion - so all session management is done in CF. There are certain interceptors in the webapp that force the Android application to perform its own functions and sometimes call external PHP scripts.

These php scripts receive the data sent to them (userid, friendid, etc.). Currently, php scripts just check to see if there is valid data that is being sent, and then process the request if the data is present and valid.

I am looking for ways to increase the security of these php scripts to prevent bots / malicious users from sending false data to these pages - at this moment nothing stopped anyone who was sending the correct userid / friendid and executing the script.

Session management will be the first line of defense, but since webapp in another language I can not use, and sometimes php scripts are in a completely different domain (the same server, though).

Another method that I considered was to create a user token for communication with the user and save it on the Android side - then when requesting these scripts, php sends the user ID and token. And confirm that the token for this user matches the remote database - this will make it difficult to guess the location of the credentials for the attacker. It is clear that this is not the best, because the token is stored locally and passes through the wire, but I'm distracted.

Question: Are there any more efficient methods to use to protect these single php scripts from running without using session management? Does my token make sense?

Note. I can use SSL for any / all requests.

+6
source share
4 answers

I know exactly what you need if you are solving a problem. Your API must implement OAuth2.0.

What OAuth can provide you with is a safe way to transfer information to and from your service server, while ensuring that all sensitive information remains confidential and that only the right people can access this information. This gives each user a unique signature.

OAuth is used by Facebook, Google, Twitter and more to give developers a secure way to access information, without letting everyone do what they don’t need to do.

OAuth supports ColdFusion, Java, PHP, C #, dotNet, VB.net, LIST, Javascript, Perl, Python, Ruby and more.

http://oauth.net/

+6
source

Session management or OAuth are the best solutions, but not the easiest. A simpler way is to implement a hash algorithm in both your application and PHP scripts. When the application prepares the request, you get some values ​​that are sent to the server using your secret method. This hash is sent with the request. The server does the same and compares the two hashes. When they match, he knows the request is from the application (or the one who cracked your algorithm). When this is not the case, the server can simply ignore the request.

Example:

Data: userid = 2042; name = JohnDoe; email = john-doe@someprovider.com

Hash (in PHP, but you should also implement it in the application):

<?php $userid = 2042; $name = 'JohnDoe' $email = ' john-doe@someprovider.com '; // Remove some letters with other letters $name = str_replace(array('a', 'd', 'g'), array('E', 'x', '9'), $name); // Reverse a string $email = strrev($email); // Make a super secret hash (with salt!) $hash = sha1('fnI87' . $useris . '87bk;s.' . $name . 'unf%gd' . $email); // Some more fun $hash = str_rot13($hash); ?> 

Request: http://www.your-server.com/script.php?userid=2042&name=JohnDoe& email=john-doe@someprovider.com & hash = YOUR-GENERATED-HASH

Now the server can apply the same hashing method and compare the received hash with the hash sent with the request.

+3
source

I would suggest a more abstract approach, but similar to Jonathan.

I make the following assumptions:

  • You have a PHP script that anyone can call (if they know the URL / sniff network packets).
  • Your Android application is closed; this means that if you have a hash algorithm nobody, but you will know what it is.
  • You want to prevent anyone from directly accessing PHP scripts - bypass the application and any security that you could build there.

What you need to do is determine that your application is sending requests, not someone else.

The idea is that you create a signature for each request that only your application can make (i.e. salt + hash).

 $input = array( "userid" => 1234, "friendid" => 2345 "etc" => "..." ); $salt = "s3kr4tsal7"; // this is essentially your app signature $signature = md5($salt . serialize($input)); // you could also use json_encode or any other to-string serialization // pick whichever is easy to do in PHP and in your app $request = array( "input" => $input, "signature" => $signature ); // send this 

Then, in your PHP script, check to see if the signature matches the calculated signature. This is similar to Jonathan's solution, but it allows you to use any input independent of $email or any other property. I also don’t think you need a too complicated hashing algorithm, just md5 with the salt is “pretty heavy”.

There is another type of attack that you should be aware of, and that is a re-attack.

If you look at the RAW data passing along the line, you can capture it and simply play it again. If you know which action has which conclusion, you can simply repeat the conclusion.

A typical re-attack solution is the trial version and response. SSL does this for you, but you can also create your own implementation (but it is much more complicated).

+2
source

As usual, it depends on what level of protection you need and how much you are willing to invest. Since you cannot use sessions, you need some kind of stateless method for authentication. Usually there are two ways to do this: send credentials every time (for example, basic authentication) or send some kind of token (BTW, the session identifier is exactly the token that refers to a live session on the server).

When you create a token, it is recommended that you use a standard and proven algorithm instead of inventing your own and / or relying on ambiguity. Even if it looks basically safe, it may not be. For example, there are known attacks against the idea of ​​MD5 above (it is easy to add data to a message without knowing the key and get another valid MAC). HMAC-SHA1 is designed to avoid this.

First of all: if you can, use SSL for all requests. This would do several things at once:

  • users (your application) can be sure that they send their data to the right place (i.e. your web address). SSL server authentication will take care of this.
  • he will make sure that any accounts / tokens that you publish will be automatically encrypted.
  • Repeated attack becomes almost impossible.

It seems that you already have authenticated users, so issuing tokens should be relatively easy. You might want to think about how to implement the protocol, but since you are considering more cases, you will be closer to redeveloping OAuth and friends. Some things to consider:

  • validity period on tokens: so even if someone takes possession of them, they cannot use it for an indefinite period.
  • token cancellation method
  • may have different tokens for different parts (services) of the web application, so you can only provide / revoke access to the necessary services.

To make sure that you (i.e. your webapp (s)) are the only ones who can issue the indicated tokens, you would like to sign them using the key that you have. Since the signer and the verifier are the same (you), you do not need to use public key cryptography, which the HMAC must do. You could, for example, combine username, release time and any other relevant information and use them as input to the HMAC. Pack these parameters together with the signature (HMAC output) to create a token, and the application will send it with each request. Check on the server and allow access if they are valid, require re-login (new token), if they expired, deny access otherwise.

Alternatively, if you want to authenticate only the application, and not enter user information into it, you can use a similar approach for signing requests on the client side (application). If you choose this method, use the standard algorithm. Of course, this will require that the signing key (in some form) be in the application, so if someone takes possession of it (by reverse engineering, etc.), they can issue as many requests as they want. There are ways to mitigate this, though:

  • implement signature logic in native code
  • Do not store the raw key, but output it at runtime from bits and pieces stored in different places.

And, of course, the easiest way would be to require basic or digest authentication on the server (of course, via SSL) and embed the username and password in the application (quite confusing). On the server side, which requires only server configuration changes, a few lines are added on the client side. The downside is that there really is no way to change these credentials if they are compromised (by not releasing a new version and blocking access from the old one to get people to update, not enough).

+2
source

Source: https://habr.com/ru/post/909706/


All Articles