Monday, July 15, 2013

Android : Security requirements for Enterprise apps

"Do not let Android application to install on rooted Android devices and on emulators"

"Delete all sensitive data as soon as application realizes that device is rooted"

"Make sure that data stored in in Android device DB is not compromised"

"Prevent reverse-engineering of Application"

These are some of the common security related requirements of most enterprise application. In this blog, I will try to list down what is feasible to implement for each of these requirements.

1.  "Do not let Android application to install on rooted Android devices and on emulators"
It is NOT possible to prevent application getting installed on rooted phones or even simulators.  So instead of trying to prevent the installation, easier solution would be check if device is rooted/emulator after launching the application, if so, just block the further access to the application.

Checking if the device is Emulator:
Android provide a simple API to check the device type.
Build.PRODUCT
if the PRODUCT is "google_sdk" then we can assume that application is being run on Simulator.
Check this link for more details
http://stackoverflow.com/questions/2799097/how-can-i-detect-when-an-android-application-is-running-in-the-emulator

Check if the device is rooted:

  • Try to execute some commands which are allowed only for super user and check the response
  • Check if  SU process is running e.t.c
Remember that none of these methods are 100% fool proof! 

Check this discussion for more information

2. "Delete all sensitive data as soon as application realizes that device is rooted"

This is a simple one, create a service and register for auto-launch on device bootup. In this service, periodically (say once in 2 minutes) check if the device is rooted (discussed above). If yes, delete all sensitive data of the application. 
WARNING: This could drain the battery. Depending on the sensitivity of the data, you can vary interval duration to save battery.

3.  "Make sure that data stored in in Android device DB is not compromised" 
"Encrypt the data base"

Simplest way to encrypt the data base in Android is to use SQLCipher. SQLCipher uses 256 bit AES encryption to encrypt the database files.

DO NOT hard-code the key in the code!! It is very difficult to prevent re-verse engineering your Android application from APK. A determined hacker can easily get hold of the key if you hard-code it in the code. Much better solution is to ..
  • Random generate this key on first launch and saving it for later use. 
  • Again, saving the key as it is could be risky. Use some algorithm to modify (encode) the key before saving it, use reverse algorithm to decode the key before using for decryption the data base. 
  • Now you might say that this is not safe solution. If code can be reverse engineered the  whats the point in encoding the key. Remember that reverse engineering tools can only provide the code logic and cannot get the exact method and variable names for obfuscated code. So, we can use a method name or a variable name (Remember Java Reflection??) in some way to encode the key, then it would be very difficult for any body to break it.
4. "Prevent reverse-engineering of Application"

There are no fool proof methods to prevent reverse-engineering. you can only make the process difficult by obfuscating the code. Try ProGaurd tool provided by Andorid.

Thursday, September 22, 2011

IPhone : Good Coding Practices

I will attempt to list down small tricks&tips which might help you keep your code clean and save lot of debugging time. Some of these are ofcourse extracted from other posts else where :-)

1. When using an NSURLConnection, as a rule you may well want to implement the delegate method:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
        return nil;
}

I find most web calls are very singular and it's more the exception than the rule you'll be wanting responses cached, especially for web service calls. Implementing the method as shown disables caching of responses. 


2. Set your properties as nonatomic. They're atomic by default and upon synthesis, semaphore code will be created to prevent multi-threading problems. 99% of you probably don't need to worry about this and the code is much less bloated and memory efficient when set to nonatomic.

3. Don't use unknown strings as format strings When methods or functions take a format string argument, you should make sure that you have control over the content of the format string. For example, when logging strings, it is tempting to pass the string variable as the sole argument to NSLog:

 NSString *aString = // get a string from somewhere;
 NSLog(aString);

The problem with this is that the string may contain characters that are interpreted as format strings. This can lead to erroneous output, crashes, and security problems. Instead, you should substitute the string variable into a format string:

 NSLog(@"aString: %@", aString);


4. This is subtle one but handy one. If you're passing yourself as a delegate to another object, reset that object's delegate before you dealloc.

- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}

By doing this you're ensuring that no more delegate methods will get sent. As you're about to dealloc and disappear into the ether you want to make sure that nothing can send you any more messages by accident. Remember self.someObject could be retained by another object (it could be a singleton or on the autorelease pool or whatever) and until you tell it "stop sending me messages!", it thinks your just-about-to-be-dealloced object is fair game.Getting into this habit will save you from lots of weird crashes that are a pain to debug.The same principal applies to Key Value Observation, and NSNotifications too.

5. Use #pragma mark [section]. Usually I group by my own methods, each subclass's overrides, and any information or formal protocols. This makes it a lot easier to jump to exactly what I'm looking for. On the same topic, group similar methods (like a table view's delegate methods) together, don't just stick them anywhere.


6. Clean up in dealloc. This is one of the easiest things to forget - esp. when coding at 150mph. Always, always, always clean up your attributes/member variables in dealloc.

Tuesday, September 20, 2011

Android : Pop to Root View


Many a times it is required that we jump back to the root activity. Something like popToRootViewController in IPhone world. For example I started activity A then B then C and from menu options I want to go to back to A. In this case instead of creating a new A activity, application design would need to pop out B and C and then refresh A with the new content.

To achieve this we can add a flag - FLAG_ACTIVITY_CLEAR_TOP  to the intent while trying to launch the activity.

Small code snippet to go to the home activity
 public static void goHome( Context ctx )  
 {  
   if ( ! ( ctx instanceof HomeActivity ) )  
   {  
     Intent intent = new Intent( ctx, HomeActivity.class );  
     intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );  
     ctx.startActivity( intent );  
   }  
 }  




Top 50 Blogs & Websites For Android Developer & User « « WebDesignerGeeks - Web Designer, Web Developer blog WebDesignerGeeks – Web Designer, Web Developer blog

Good Compilation of the Top Blogs related to Android development

Android : Top 50 Blogs & Websites For Android Developer & Users

'via Blog this'