I'm designing a location-based service where reliability plays a role.
I wish my users to know that the provided location of other users is real.
I researched mock locations a bit, and noticed in this thread the app LocationSpoofer. I don't have a rooted phone currently, but it states that when rooted it can mock locations even without the setting.
Is there any known way to protect against that? I could use some simple heuristic to verify that the user didn't travel from France to Hawaii in 30 minutes, but I would rather have complete protection.
Thanks ahead!
Instead of a long comment:
"reliability plays a role"
As long as your provide reliable output for "reliable" input i think you will be OK without having to handle 'spoofed' or fake input. In case you have data stored in persistent storage you could handle cases for 'suspicious' data.
That is define and apply scenarios on your data to identify cases like "the user traveled from France to Hawaii in 30 minutes", and handle such cases in an appropriate way. Or you could even reject data that are not realistic.
From a security point of view you should assume that any data coming from a client-side validation process cannot be trusted. The data could be intentially, or unintentionally, modified and that is out of your direct control.
If you want to protect against location spoofing then I would recommend server side checks.
Related
Though as a beginner, I am trying to develop an android app which is story based, i will like to know the best way to serve content to the user, i mean like a continuous update of content, just like updating news by the hour. As users will install just once, how will they get the latest content of my news or story based app.
I have access to domain names and hosting if it requires uploading such content through a domain.
from your experience, what is the best method to achieve this? I humbly await a response, thanks
So given the clarification in the comments this is the answer:
The best way is PUSHING the content to the user's device.
Generally speaking, the two ways for a new content to reach an app are :
1.polling your server (or any third-party server) for new data every,say, 20 minutes. The disadvantage of this method is that it drains the battery. Every time that the phone connects to the internet, the radio in that phone stays on (or in a standby mode) for something like 2 minutes. Those modes (on and standby) drain the battery. Another problem is that it does use data needlessly and in some countries cellular data is expensive (Canada for example).
This could be a solution if the data changes very very frequently (for example a stock's price can change many many times a day). But generally speaking method 2 is the preferred method..
2.Pushing the content to the user's phone.
Your server will send a message to the device once new data that you want to send is there (and you could also put that data in the payload of the message if it's not too much).
This means that the phone will connect only when some new data is available.
Saves battery life,and gets the information as soon as it is available!
I recommend using GCM (Google Cloud Messaging) for this purpose which is free, and simple to use. If you have no idea how to do that in Android (which is likely since you said that you are a beginner), it is explained really well in Udacity's
Advanced Android App Development. It is a free course by Udacity and Google, but the section about GCM is only about 15 minutes long.
If you know how to implement a server but don't know how to use GCM in your server (and you don't find Google's documentation helpful) do let me know..
If you don't know how to implement a server...well then it's something you will have to learn in order to get your content to your users as that's the best way.
I hope this helps! :)
What I want to do is is there a very way to prevent user from turning off Mobile Data & Location services?
My scenario is this, I am creating a mobile application for a big project we have now. This application is restricted for the use of their employees going out of the field, now this phone by any means should not turn off mobile data and location services as I have an application service that sends constant location data to the administration API.
OR maybe an existing application that prevent native functions like this from being accessed. This may sound crazy but I just have thought if there is something like this.
Thank you!
I hope someone could enlighten me.
No, you can't do that.
Even if you could, it would not solve anything, because there are many other reasons why those services may not work. For example when one is driving through a tunnel and there is no signal or out of town there may sometimes be no signal or the network may be overloaded or something. So you can't rely on these services anyway. Intermittent loss of connectivity is pretty common in mobile devices. You will have to take it into account (log data and send them when you succeed in reconnecting).
If the users need the application, and connectivity in it, to do their job, they won't be turning it off, because they need it. So all that is needed is to create a notification when connectivity and/or location is lost so the user can do something about it if:
the application fails to connect when they turn it on at the start of their shift or
the application looses connection for extended period of time for whatever reason.
And of course if there is somebody in the company using the data (some dispatcher), which I suppose there is, they will notice the particular worker is not sending anything and will try to contact them by calling or something. These should take care of mistakes and faults.
If the users don't need it and it is intended to spy on them (so they may have a reason to disable it), it is probably illegal anyway.
You cannot prevent user from turning off Mobile data. But you can simple record location in a file with time while data is off and send it immediately after user turn on the data.
That is impossible unless the device is rooted.
And it makes perfect sense, because that would compromise the user's experience of Android and/or security.
You must anticipate circumstances like the user turning off the data or connection and act appropriately (for example gracefully stall your connections with the internet and resume them later, inform the user that his device has been disconnected from the internet and that your application requires internet access etc...).
We have an android(or iphone) client we are developing. The client allows the android user to send entries to a server which we also develop. If the client does not have data services (GPRS) at the moment the user sends the entry to the server, the client also supports saving the entry to an offline database and sending it later to the server.
One important aspect of the whole process is accuracy of the timestamps on which the user sent the entry to the server (whether the entry is made in real time or sent by the client from the offline database)
When available on the client, we get a GPS location and are able to use the GPS timestamp to send that to the server (or save the GPS timestamp on the offline DB and send it later to the server). However if the user has turned off the GPS (and all other location services), the device will not have a GPS fix and therefore the server can not determine accurately when an entry was made.
We can not use the local device clock as the user may change the clock to make entries on different times than they actually occurred (these entries are part of the users salary so he might have an interest to "fix" them).
So basically I am searching for a way to determine as best I can the time some entry was made when I can not trust the internal clock of the mobile. The algorithm should support both entries sent in real time or entries sent from an offline DB. the algorithm should also support cases where the user changes the time of the mobile, turns the mobile on/off, turns the GPS on/off while the application is running on the mobile etc...
Few ideas that I thought of:
Although I can not trust the mobile's time, it can still perform as a stop watch:
Have a class that will loop until the application exists, the loop will sleep 1 second and increase an internal clock variable by 1 second. On every GPS location my code gets we update the internal clock variable. This way I have an absolute clock that came from outside the device (from the GPS) and when the client sends an entry to the server, we can use the internal clock as an absolute time.
PROS: the user can not modify this clock as it is only updated when we get a location from the GPS
CONS: the application needs at least one GPS fix before the user can make any reliable entries
I can take advantage of the fact that the server has an accurate clock which is correct. If the client would send to the server info that the age of the entry is 10 minutes, the server could use its internal time and know the exact time the entry was made on.
The biggest problem is how to know the entry age? I thought about saving the entries to the offline DB with an age of 0, then every 1 second increase the age of the entry in the DB. The problem is that if the app is closed and/or the device is off this will now happen
This is where I am currently stuck. Any ideas on how to solve this are more than welcome
Thanks
Here's how I handle this issue for iPhone. When the app starts, I call my server and ask for the current GMT time (you could also call a public NTP server if you preferred). I then compare it to the system time. If it is different by more than X then I popup a message saying, sorry your system time is wrong so you can't use the app until you fix this. I then monitor for the user changing the system time while the app is running and if they do that, then I do the compare again (and popup the error message if the time is off by more than X). This ensures that their system time is always correct (within some reasonable allowance) and you can trust [NSDate date]. However, this solution does require a valid network connection. If this solution works for you, I can post the sample code.
i think i am going to combine Jules and Joel's answers into one solution which will provide for my needs the best solution:
since the user might change the clock when the mobile doed not have GPRS, just detecting the time change event will not help us as we can not validate at that moment the new time is correct.
As Joel recommended i will pull the time from my server when my application is started (at that point i still must have communications with the server or else my application will not start). The time pulled from the server along with the current device upTime will be saved.
when the user wants to make an entry i will calculate the current time using (Server Base Time + Current UpTime - Base UpTime). this way i will have an independent source of time regardless of the current clock of the device
this will defenitly work on android
on iPhone we will try to use something out of http://www.cocoadev.com/index.pl?FindingUptime to get the upTime
Jules & Joel, thanks for your answers!
Look into android.os.SystemClock. Specifically, elapsedRealtime() returns a time since the phone was switched on, which is not affected if the clock is changed by the user.
You can correlate times in event the phone is switched off by having code that runs when it is switched on and checks the realtime clock. As the clock can't be changed when the phone is off, I suspect you could use this to put together a system that will catch any simple attempts at cheating. (If the user roots the phone all bets are off -- they could modify the behaviour of the APIs from under you).
Running code every second will kill the phone's battery life. Most phones would be unlikely to last a day if you did this.
I'm developing an application on both the android and iPhone simultaneously. Due to the nature of my geolocation application, it's important that the information is really coming from a phone, and not just an emulator that happens to have the application installed.
Is there some kind of value I can pull from the device(s) to determine if its an emulator? I don't want users cheating the system by simply setting their own values for their lat/long coordinates. I know nothing is fool proof, but I would at least like eliminate as much fraud as possible.
I plan to have algorithms in place to validate data being recieved, such as jumping n. miles in n. seconds from your last location -- but this could cause false positives in some situations -- especially on some Androids, where you can magically be placed all over the world moving 2 feet.
This is applicable to both the Android and iOS. Answers for either phone would be fine.
You can use [UIDevice currentDevice].model to get the current device model for iOS. The UIDevice class reference will give you the possible constant strings which you can compare to. Scroll down to the model property for more info.
Don't have much experience with android, however this should work.
With Android, as it turns out, it's a bit more complicated than just determining whether or not you're on an emulator (which can be done using Peter's link above), given the ability, under "Development Settings" to allow Mock Locations (see, for example, this app that allows the user to set a mock location that will then be made available to other apps).
Depending upon the method you're using to retrieve the location provider (e.g., calling LocationManager.getProvider() using the return value from LocationManager.getBestProvider()) you could therefore end up using a Mock Provider. I've been unable to find any definitive method for determining whether a provider is Mock or not (e.g., there's no property of the LocationProvider that indicates it is Mock, no property of the Location that indicates it's fake, etc.). What you could, however, do is read the Secure Settings to determine whether or not ALLOW_MOCK_LOCATION is enabled and not allow your app to function in this case; since the setting is one of the Secure Settings, there is no way to change it programmatically.
I am trying to figure out the meaning of setCostAllowed() setting for GPS criteria. Android documentation says "Indicates whether the provider is allowed to incur monetary cost."
Who cares if provider is incurring any costs? I never seen a line on mobile bill that says "gps charges". Has anyone ever been charged for this?
If not, why not just set it always to 'true' and forget?
Ideally this is something I'd like to give the end user control over, however putting this option in application GUI may only raise more questions to which I don't myself have an answer. Does anyone have an explanation for this setting?
The reason for the setting is that not all mobile plans include an unlimited data package, thus customers are charged a per-use fee for data, which includes GPS data. So, it's necessary to ask users if it's okay to incur costs on their behalf for data that your application consumes (i.e.: give them the opportunity to opt-out).
The Criteria for requestLocationUpdates is used to choose the 'appropriate' provider depending on the parameters specified in the Criteria. Sometimes this may refer to having the NETWORK_PROVIDER which in-turn may result in a data connection having some cost incurred on the user.