Check If Http Request Comes from My Android App

Check if http request comes from my android app

Android requires that one should sign their app(signing authority or self signed) before it can be installed. We can utilize this to check whether requests are coming from your app or not.

  1. Sign your app with your certificate.
  2. Find the certificates signature and save it in your backend server.
  3. For every request, expect this signature to be sent by the app.
  4. validate the signature sent by the app at server level and accept only if they matches.

Even in that case where someone tampers with your app, he has to sign it again before it can be installed, which would change the apps signature and our validation mechanism would simple reject all such requests.

This answer is based on this blog. Use https for app<->server communication.

Identify whether HTTP requests from Android App or not? and then respond appropriately

You can add a signature to the request and then check it on server-side.

Just take the query and add one secret word at the end, then make a MD5 of it that you can send as an header (or use as a user-agent). And on the server you do the same and check if the checksum is the same.

To make it a bit safer you can make a timestamp so the request only will be valid for a short time.

Make your query look like http://example.com/abc.php?usera=abc&datab=xyz×tamp=123456789 where timestamp is the current time (in unix time stamp) and add this in your app:

public static String makeCheck(String url)
{
URL u=new URL(url);
MessageDigest md = MessageDigest.getInstance("MD5");
u.getQuery();
md.update(u.getQuery().getBytes());
BigInteger bn = new BigInteger(1,md.digest("A_SECRET_WORD".getBytes()));
return bn.toString(16);
}

And when you need to add the header use something like:

request.addHeader("X-CHECKSUM", makeCheck(url) );

Then on your server you can use:

if (md5($_SERVER['QUERY_STRING']."A_SECRET_WORD")!=$_SERVER['X-CHECKSUM']) {
// Wrong checksum
}

$timediff=60;

if ( $_GET['timestamp']>(time()+$timediff) || $_GET['timestamp']<(time()-$timediff) ) {
// Bad timestamp
}

Remember to be a bit slack on the timestamp since your servers clock and the phones clock can be off sync a bit.

How to verify https requests coming from android app on server side?

Typical HTTPS allows a client to verify that it's talking to the server it expects. You want that, but also to have the server verify that it's talking to a well known client. This is known as mutual authentication.

Implementing this is beyond the scope of what I could describe here, but if you google the topic it will get you started. As is the case with all security mechanisms, don't roll your own. You will almost certainly make mistakes that have already been made and resolved by others.

How to detect if request came from mobile device

The general answer is no. You get a header / message from a device. All you know about the device is in the header and the device can write what it wants in it. If you are talking about http requests (which is indicated by agent lookup) you can look at a header here:

All you can do "reliable" is to look for the user agent. In my case it is Mozilla Firefox on Linux. But I could fake it if I want.

Host: somesite.org
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://somesite.org/index.php?page=2
Cookie: rteStatus=rte;
Cache-Control: max-age=0

Maybe you can get some informations from the referer if it is some chromium-mobile site or you can have a look at Accept and Accept-Enconding, maybe some mobile browsers accept different stuff. But there is no reliable way to determine the device but by its user Agent via header.

An other approach is to look if the request comes from an IP known as 3G or 4G pool. But this would just work if the requests is not coming via WLAN / WIFI. And I am not sure if a list of 3G / 4G IP address pools exists.



Related Topics



Leave a reply



Submit