I'm trying to get androids new In-APP Billing to work with unlockable content.
For example, the user can unlock special content for a limited time.
The content comes from a web service, the problem I have is, how do I know when the user can view the content?
Because the user can buy it multiple times I use the items unmanaged.
So I somehow have to store the users information in my service, so I can provide content when he is allowed to.
The problem is that I don't have any information about the user, no ID, only a orderid which is not remembered by google.
So if he changes phone or wipes the database the access is lost.
What is the best possible way ensure the user has access to the content?
The only way i can think of is to store it on a remote server, where you could keep the data of who has what.
To create an ID for a user you could do some type of UUID creation see:
http://android-developers.blogspot.com/2011/03/identifying-app-installations.html
Related
When a user logs in from my app, I receive a user-id from the API on a successful login. That ID is then used throughout the app to interact with the API. Currently, I am storing that ID in shared preferences. However, a user with root access can easily change the ID, thus identifying as someone else they are not.
How should I store this id without causing security risk? If this isn't possible what are other alternatives to this?
It sounds like the problem is fundamentally that your app is trusting the user to tell the app who they are via this user ID. What your app should most likely be returning, and passing back to the app for API use, is a cryptographically based session token that the app knows how to unpack to determine the user's identity, but the user has no way of altering without invalidating it.
I am thinking of creating a app that will contain personal user information for a memberships scheme, the basics, name, dob, a user ID and a valid from / expiry date.
I want to reduce the instance of hacking and having the data stolen. So I was thinking that I add the user information in the database, when the user logs in for the first time, the app connects to the data and downloads the users information to their phone and all personal data is removed from the database, the ID is used for the app to display valid from/expiry dates etc.
I am unfamiliar with iOS/Android app development. Can this work, do I store in a separate file and download to a user area in the app package or do I download a database to the phone, and what about when I need to update the app?
This is not good system design
In reality if a system is designed properly, with a security focussed mindset and deployed in a properly designed environment, this should not be a concern that warrants causing end users such potential issues.
In fact, user data would be considerably more secure on a properly designed, controlled system than on a user's device; How many people do you know that don't have a passcode on their phone, or have it set as their date of birth? I know a whole bunch of these types of people (and by logical extension, the passcodes to their phones).
You also mentioned that the data will be deleted from the database. How exactly will it end up back in that database in the event of a support ticket? If it's by emailing it back to you, that would be a bigger security risk because plain text email is not secure.
What you should do instead
Build a web service to sit between your app and the database
Pass the login details from the application to the web service and perform authentication/authorisation there. If successful, pass back an access token of some description. Save this access token to the database with an expire-time value.
Have the app call various api endpoints, passing the access token as part of the Authorization header (so it doesn't get cached or end up in the logs of proxies and web servers etc). If the token is valid, fulfil the request and return the requested data back to the app from the web service
On log-out/quit, have the app remove any sensitive information from the device memory if security is such a concern.
Additional Notes
As with any such design, you should ensure that all communications are done over a secure channel.
Ensure passwords are stored in a secure format and not transmitted or stored in plaintext anywhere. Use a secure channel for passwords in transit, Bcrypt is good for storing passwords or consider implementing Secure Remote Password Protocol.
Ensure that direct access to the database is only allowed from your web service and not the wider internet
Ensure that your webservice sanitises input, escapes output and is not vulnerable to SQL Injection attacks.
The benefits of this approach are obvious:
Your app data remains secure so long as the environment is secured using the correct tools. If you choose the right hosting provider they'll also be able to provide help and support securing your web server and database.
In the event of a user changing their device, logging out or whatever else they'll be able to log back in as they see fit. This will meet the already well established expectations of users and reduce potential support calls.
If you decide to expand on the features of your app later on, you can add new tables to the database, new endpoints to the webservice and new functionality within the app to consume said endpoints.
Many users tend to have a bad habit of reusing passwords; With a properly designed system you're able to audit login attempts, lock users out for a period of time after so many incorrect password attempts, force password expiry or resets and allow for self servicing of password changes to the whims of your more security conscious users.
I'm new with android apps developing. For now, I'm only capable to link the activities through buttons. For my app, I will need to know how to store user information so the same user can view his information even with a login from another device.
I saw in the official Android documentation the methods how data can be stored and the only one that seems to be useful in this case is Databases. How can I use this method (or another method to, if you know) for my aim?
If you want data to be accessible from other devices, you need to store the data on a remote server and expose it through an API. Then in your Android app you would hit your API to pull down / store the user's data when needed. You could also store the data from the API locally in a MySQL database. If done correctly, this can help minimize network calls and maximize functionality when the network is not available. We can take a small example.
Let's say you have an app where the user just enters a number, and it gets stored on your backend + displayed in a TextView. Anytime the user logs in on any device, you want that user's number to appear in the textview.
Here is how you would do that: First have your user log in. This can be done with numerous frameworks. Once the user is logged in, you would check to see if that user already has a number stored in your backend. If so, you pull it down and display it on the textview. If not, you just display the blank textview. When the user enters a new number, you make a POST request to your API to tell it that this user wants to store a new number. Then this number would be stored and available on any device the user logs in on.
The remote server is a must for working with shared user data. For simple user data, however, I recommend a Firebase RealTime database or Firebase Firestore.
You will save a lot of power.
I know very little about security or servers, but am making an Android app that allows users to purchase an in-app subscription. As recommended, I want to use the Google Play Developer API and store the necessary data on my own server. However, I can't think of a way to do this without having a line in my code like
if(userIsSubscribed){
//give access to purchased data
}
A hacker could obviously go in and just flip that to if(true). What should I do instead?
Obfuscate your app code as a minimum. Also do the subscription check on the server, before you send the content. That is one of the reasons they have an Web API.
Basically, anything the user (and potential cracker) has access to (i.e., your app) cannot be trusted. Things they don't have direct access to (i.e., your content server) can be trusted a bit more and it is a good idea to move all sensitive operations and/or data there, where possible.
I'm attempting to implement a system for upgrading/unlocking various features of my app using "managed" purchases with in-app billing, and I'm getting bogged down by the lack of in-depth documentation or examples.
My app's purpose is to retrieve/parse and display data from my own server, and the documentation on http://developer.android.com/guide/market/billing/billing_best_practices.html states:
If you are using a remote server to deliver or manage content, have your application verify the purchase state of the unlocked content whenever a user accesses the content.
My question is, what is the best way to go about this in terms of actual workflow?
As far as I can tell, on successful purchase I would store the purchase information on my server as well as locally in the app. When the app runs, I would send the order ID to my server and the server would check to see if the order is valid (firstly checking that the order exists in my server's database, and secondly checking if I have not manually revoked the order for whatever reason).
If that is verified, the server would send a response to the app that the requested features are "licensed", and the app would provide the unlocked features/content to the user.
The obvious problems I can see with this are:
A rooted user could easily just alter the local app's SQLITE database (or whatever other method I use to store order information) to inject a valid order ID.
If network access is down, or my server is down, I still want the app to be able to run (with cached data) with all the user's purchased features.
Potential ways around the first problem that I can see involve sending some sort of device identifier with the verification request, and monitoring that at my server's end - revoking the order if a large number of devices are accessing the order in a short period of time.
For the second problem, I can't figure out an adequate solution. I initially thought that each time the verification is successful, the time this verification took place would be stored. Then, the app would continue to run with the unlocked features for say, 48 hours after the last successful verification. The issue with that is, how can I securely store this time value? Again, rooted users could simply alter the value and the app would be none-the-wiser.
Has anyone designed a server-based system for managing in-app billing purchases and can offer some suggestions?
Google Licensing provides a way to allow a cached 'You're license is valid' response to stay alive.
Application Licensing
You can also encrypt the data your are storing. If they have paid for it, they get to decrypt it. If no network access available, then implement a similar caching scheme as Application Licensing (currently licensed under the Apache License, Version 2.0).