android
27 TopicsBIG-IP Edge Client 2.0.2 for Android
Earlier this week F5 released our BIG-IP Edge Client for Android with support for the new Amazon Kindle Fire HD. You can grab it off Amazon instantly for your Android device. By supporting BIG-IP Edge Client on Kindle Fire products, F5 is helping businesses secure personal devices connecting to the corporate network, and helping end users be more productive so it’s perfect for BYOD deployments. The BIG-IP® Edge Client™ for all Android 4.x (Ice Cream Sandwich) or later devices secures and accelerates mobile device access to enterprise networks and applications using SSL VPN and optimization technologies. Access is provided as part of an enterprise deployment of F5 BIG-IP® Access Policy Manager™, Edge Gateway™, or FirePass™ SSL-VPN solutions. BIG-IP® Edge Client™ for all Android 4.x (Ice Cream Sandwich) Devices Features: Provides accelerated mobile access when used with F5 BIG-IP® Edge Gateway Automatically roams between networks to stay connected on the go Full Layer 3 network access to all your enterprise applications and files Supports multi-factor authentication with client certificate You can use a custom URL scheme to create Edge Client configurations, start and stop Edge Client BEFORE YOU DOWNLOAD OR USE THIS APPLICATION YOU MUST AGREE TO THE EULA HERE: http://www.f5.com/apps/android-help-portal/eula.html BEFORE YOU CONTACT F5 SUPPORT, PLEASE SEE: http://support.f5.com/kb/en-us/solutions/public/2000/600/sol2633.html If you have an iOS device, you can get the F5 BIG-IP Edge Client for Apple iOS which supports the iPhone, iPad and iPod Touch. We are also working on a Windows 8 client which will be ready for the Win8 general availability. ps Resources F5 BIG-IP Edge Client Samsung F5 BIG-IP Edge Client Rooted F5 BIG-IP Edge Client F5 BIG-IP Edge Portal for Apple iOS F5 BIG-IP Edge Client for Apple iOS F5 BIG-IP Edge apps for Android Securing iPhone and iPad Access to Corporate Web Applications – F5 Technical Brief Audio Tech Brief - Secure iPhone Access to Corporate Web Applications iDo Declare: iPhone with BIG-IP Technorati Tags: F5, infrastructure 2.0, integration, cloud connect, Pete Silva, security, business, education,technology, application delivery, ipad, cloud, context-aware,infrastructure 2.0, iPhone, web, internet, security,hardware, audio, whitepaper, apple, iTunes2.5KViews0likes3CommentsBlock access to apps by browser. Allow only iPhone or Android accesss
Customer has an application that they want access only through the mobile device app. They have recently found that the application can be accessed through any browser. We have configured the following iRule but it is not working: when HTTP_REQUEST { if { ([HTTP::header User-Agent] contains "iphone") or ([HTTP::header User-Agent] contains "Android") } { HTTP::redirecthttp://www.oursite.com} if { ([HTTP::header User-Agent] contains "(IE|Mozilla|Safari|Chrome|Opera)") } { drop } } Any ideas how to achieve this? Thanks1.3KViews0likes5CommentsRDP using Android or iOS Edge client apps
I have been able to use the F5 Edge client to give network access to Android/iPhone users. However, it is not clear how to give RDP access to those users. This is useful for network admins who are in transit, and need to quickly jump into their computer.683Views0likes10CommentsMultiple language support for Android F5 Access 3.0.8
As noted in K02242270, F5 Access 3.0.8 for Android does not provide the "Accept-Language" header in the initial request to the Big-IP. In order to provide support for multiple languages it is necessary to inspect the traffic that arrives a bit later on in the handshake process. The following irule allows the default language to be overridden with (in this case) French. when CLIENT_ACCEPTED { # # Required so that "when HTTP_REQUEST" can be used to patch the language issue with F5 Access for Android. # ACCESS::restrict_irule_events disable } when HTTP_REQUEST { # # Access policy default language is English. Look for French OS. # if { [HTTP::path] equals "/my.policy" && [HTTP::method] equals "POST" && !([HTTP::cookie exists "LastMRH_Session"]) && [string match "fr*" [HTTP::header "Accept-Language"]]} { ACCESS::session data set session.ui.lang "fr" } } Note that the Accept-Language header is correctly supplied by the F5 VPN clients for Windows, Mac and iOS. The iRule is required for Android only. If using this in a mixed environment then you would likely want to add a check for [HTTP::header User-Agent] contains "Android" to the if statement.533Views0likes1CommentF5 APM and external mobile application log in
Hi everybody, I'm a beginner and i start looking for solutions to create a connection between an IOS and Android and our F5 APM module. So far we're using mobile web application instead of mobile native application. In that case it's easier, we're using the native logon F5 form to establish a connection between the mobile browser (any browser in fact) from internet to our web mobile site in our Intranet. The idea 'll be to use the same mecanism but from our native apps. I already know that it's possible to use an external logon form (src : [https://devcentral.f5.com/questions/how-to-use-apm-external-logon-pages] ), i guess we could use something like that in our case. The mobile app will send the connection data with an http post request like the form to implement on the example before. If anybody has implemented this kind of solutions using F5 APM i would be very pleased to know how it's possible. Thanks, Xavier.438Views0likes3CommentsAndroid Encrypted Databases
The Android development community, as might be expected, is a pretty vibrant community with a lot of great contributors helping people out. Since Android is largely based upon Java, there is a lot of skills reusability between the Java client dev community and the Android Dev community. As I mentioned before, encryption as a security topic is perhaps the weakest link in that community at this time. Perhaps, but since that phone/tablet could end up in someone else’s hands much more easily than your desktop or even laptop, it is something that needs a lot more attention from business developers. When I set out to write my first complex app for Android, I determined to report back to you from time-to-time about what needed better explanation or intuitive solutions. Much has been done in the realm of “making it easier”, except for security topics, which still rank pretty low on the priority list. So using encrypted SQLite databases is the topic of this post. If you think it’s taking an inordinate amount of time for me to complete this app, consider that I’m doing it outside of work. This blog was written during work hours, but all of the rest of the work is squeezed into two hours a night on the nights I’m able to dedicate time. Which is far from every night. For those of you who are not developers, here’s the synopsis so you don’t have to paw through code with us: It’s not well documented, but it’s possible, with some caveats. I wouldn’t use this method for large databases that need indexes over them, but for securing critical data it works just fine. At the end I propose a far better solution that is outside the purview of app developers and would pretty much have to be implemented by the SQLite team. Okay, only developers left? Good. In my research, there were very few useful suggestions for designing secure databases. They fall into three categories: 1. Use the NDK to write a variant of SQLite that encrypts at the file level. For most Android developers this isn’t an option, and I’m guessing the SQLite team wouldn’t be thrilled about you mucking about with their database – it serves a lot more apps than yours. 2. Encrypt the entire SD card through the OS and then store the DB there. This one works, but slows the function of the entire tablet/phone down because you’ve now (again) mucked with resources used by other apps. I will caveat that if you can get your users to do this, it is the currently available solution that allows indices over encrypted data. 3. Use one of several early-beta DB encryption tools. I was uncomfortable doing this with production systems. You may feel differently, particularly after some of them have matured. I didn’t like any of these options, so I did what we’ve had to do in the past when a piece of data was so dangerous in the wrong hands it needed encrypting. I wrote an interface to the DB that encrypts and decrypts as data is inserted and removed. In Android the only oddity you won’t find in other Java environments – or you can more easily get around in other Java environments – is filling list boxes from the database. For that I had to write a custom provider that took care of on-the-fly decryption and insertion to the list. My solution follows. There are a large varieties of ways that you could solve this problem in Java, this one is where I went because I don’t have a lot of rows for any given table. The data does not need to be indexed. If either of these items is untrue for your implementation, you’ll either have to modify this implementation or find an alternate solution. So first the encryption handler. Note that in this sample, I chose to encode encrypted arrays of bytes as Strings. I do not guarantee this will work for your scenario, and suggest you keep them as arrays of bytes until after decryption. Also note that this sample was built from a working one by obfuscating what the actual source did and making some modifications for simplification of example. It was not tested after the final round of simplification, but should be correct throughout. package com.company.monitor; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import android.util.Base64; public class DBEncryptor { private static byte[] key; private static String cypherType = cypherType; public DBEncryptor(String localPass) { // save the encoded key for future use // - note that this keeps it in memory, and is not strictly safe key = encode(localPass.getBytes()).getBytes(); String keyCopy = new String(key); while(keyCopy.length() < 16) keyCopy = keyCopy + keyCopy; byte keyA[] = keyCopy.getBytes(); if(keyA.length > 16) key = System.arraycopy(keyA, 0, key, 0, 16); } public String encode(byte [] s) { return Base64.encodeToString(s, Base64.URL_SAFE); } public byte[] decode(byte[] s) { return Base64.decode(s, Base64.URL_SAFE); } public byte[] getKey() { // return a copy of the key. return key.clone(); } public String encrypt(String toEncrypt) throws Exception { //Create your Secret Key Spec, which defines the key transformations SecretKeySpec skeySpec = new SecretKeySpec(key, cypherType); //Get the cipher Cipher cipher = Cipher.getInstance(cypherType); //Initialize the cipher cipher.init(Cipher.ENCRYPT_MODE, skeySpec); //Encrypt the string into bytes byte[ ] encryptedBytes = cipher.doFinal(toEncrypt.getBytes()); //Convert the encrypted bytes back into a string String encrypted = encode(encryptedBytes); return encrypted; } public String decrypt(String encryptedText) throws Exception { // Get the secret key spec SecretKeySpec skeySpec = new SecretKeySpec(key, cypherType); // create an AES Cipher Cipher cipher = Cipher.getInstance(cypherType); // Initialize it for decryption cipher.init(Cipher.DECRYPT_MODE, skeySpec); // Get the decoded bytes byte[] toDecrypt = decode(encryptedText.getBytes()); // And finally, do the decryption. byte[] clearText = cipher.doFinal(toDecrypt); return new String(clearText); } } So what we are essentially doing is base-64 encoding the string to be encrypted, and then encrypting the base-64 value using standard Java crypto classes. We simply reverse the process to decrypt a string. Note that this class is also useful if you’re storing values in the Properties file and wish them to be encrypted, since it simply operates on strings. The value you pass in to create the key needs to be something that is unique to the user or tablet. When it comes down to it, this is your password, and should be treated as such (hence why I changed the parameter name to localPass). For seasoned Java developers, there’s nothing new on Android at this juncture. We’re just encrypting and decrypting data. Next it does leave the realm of other Java platforms because the database is utilizing SQLite, which is not generally what you’re writing Java to outside of Android. Bear with me while we go over this class. The SQLite database class follows. Of course this would need heavy modification to work with your database, but the skeleton is here. Note that not all fields have to be encrypted. You can mix and match, no problems at all. That is one of the things I like about this solution, if I need an index for any reason, I can create an unencrypted field of a type other than blob and index on it. package com.company.monitor; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DBManagernames extends SQLiteOpenHelper { public static final String TABLE_NAME = "Map"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_LOCAL = "Local"; public static final String COLUMN_WORLD = "World"; private static int indexId = 0; private static int indexLocal = 1; private static int indexWorld = 2; private static final String DATABASE_NAME = "Mappings.db"; private static final int DATABASE_VERSION = 1; // SQL statement to create the DB private static final String DATABASE_CREATE = "create table " + TABLE_NAME + "(" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_LOCAL + " BLOB not null, " + COLUMN_WORLD +" BLOB not null);"; public DBManagernames(Context context, CursorFactory factory) { super(context, DATABASE_NAME, factory, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub // Yeah, this isn't implemented in production yet either. It's low on the list, but definitely "on the list" } // Assumes DBEncryptor was used to convert the fields of name before calling insert public void insertToDB(DBNameMap name) { ContentValues cv = new ContentValues(); cv.put(COLUMN_LOCAL, name.getName().getBytes()); cv.put(COLUMN_WORLD, name.getOtherName().getBytes()); getWritableDatabase().insert(TABLE_NAME, null, cv); } // returns the encrypted values to be manipulated with the decryptor. public DBNameMap readFromDB(Integer index) { SQLiteDatabase db = getReadableDatabase(); DBNameMap hnm = new DBNameMap(); Cursor cur = null; try { cur = db.query(TABLE_NAME, null, "_id='"+index.toString() +"'", null, null, null, COLUMN_ID); // cursors connsistently return before the first element. Move to the first. cur.moveToFirst(); byte[] name = cur.getBlob(indexLocal); byte [] othername = cur.getBlob(indexWorld); hnm = new DBNameMap(new String(name), new String(othername), false); } catch(Exception e) { System.out.println(e.toString()); // Do nothing - we want to return the empty host name map. } return hnm; } // NOTE: This routine assumes "String name" is the encrypted version of the string. public DBNameMap getFromDBByName(String name) { SQLiteDatabase db = getReadableDatabase(); Cursor cur = null; String check = null; try { // Note - the production version of this routine actually uses the "where" field to get the correct // element instead of looping the table. This is here for your debugging use. cur = db.query(TABLE_NAME, null, null, null, null, null, null); for(cur.moveToFirst();(!cur.isLast());cur.moveToNext()) { check = new String(cur.getBlob(indexLocal)); if(check.equals(name)) return new DBNameMap(check, new String(cur.getBlob(indexWorld)), false); } if(cur.isLast()) return new DBNameMap(); return new DBNameMap(cur.getString(indexLocal), cur.getString(indexWorld), false); } catch(Exception e) { System.out.println(e.toString()); return new DBNameMap(); } } // used by our list adapter - coming next in the blog. public Cursor getCursor() { try { return getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null); } catch(Exception e) { System.out.println(e.toString()); return null; } } // This is used in our list adapter for mapping to fields. public String[] listColumns() { return new String[] {COLUMN_LOCAL}; } } I am not including the DBNameMap class, as it is a simple container that has two string fields and maps one name to another. Finally, we have the List Provider. Android requires that you populate lists with a provider, and has several base ones to work with. The problem with the SimpleCursorAdapter is that it assumes an unencrypted database, and we just invested a ton of time making the DB encrypted. There are several possible solutions to this problem, and I present the one I chose here. I extended ResourceCursorAdapter and implemented decryption right in the routines, leaving not much to do in the list population section of my activity but to assign the correct adapter. package com.company.monitor; import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ResourceCursorAdapter; import android.widget.TextView; public class EncryptedNameAdapter extends ResourceCursorAdapter { private String pw; public EncryptedHostNameAdapter(Context context, int layout, Cursor c, boolean autoRequery) { super(context, layout, c, autoRequery); } public EncryptedHostNameAdapter(Context context, int layout, Cursor c, int flags) { super(context, layout, c, flags); } // This class must know what the encryption key is for the DB before filling the list, // so this call must be made before the list is populated. The first call after the constructor works. public void setPW(String pww) { pw = pww; } @Override public View newView(Context context, Cursor cur, ViewGroup parent) { LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return li.inflate(R.layout.my_list_entry, parent, false); } @Override public void bindView(View arg0, Context arg1, Cursor arg2) { // Get an encryptor/decryptor for our data. DBEncryptor enc = new DBEncryptor(pw); // Get the TextView we're placing the data into. TextView tvLocal = (TextView)arg0.findViewById(R.id.list_entry_name); // Get the bytes from the cursor byte[] bLocal = arg2.getBlob(arg2.getColumnIndex(DBManagerNames.COLUMN_LOCAL )); // Convert bytes to a string String local = new String(bSite); try { // decrypt the string local = enc.decrypt(local); } catch(Exception e) { System.out.println(e.toString()); // local holds the encrypted version at this point, fix it. // We’ll return an empty string for simplicity local = new String(); } tvSite.setText(local); } } The EncryptedNameAdapter can be set as the source for any listbox just like most examples set an ArrayAdapter as the source. Of course, it helps if you’ve put some data in the database first . That’s it for this time. There’s a lot more going on with this project, and I’ll present my solution for SSL certificate verification some time in the next couple of weeks, but for now if you need to encrypt some fields of a database, this is one way to get it done. Ping me on any of the social media outlets or here in the comments if you know of a more elegant/less resource intensive solution, always up for learning more. And please, if you find an error, it was likely introduced in the transition to something I was willing to throw out here publicly, but let me know so others don’t have problems. I’ve done my best not to introduce any, but always get a bit paranoid if I changed it after my last debug session – and I did to simplify and sanitize.407Views0likes0CommentsQ. The Safest Mobile Device? A. Depends
Depends?!? Well, isn't that the answer to a lot of things in this world? Often our answer depends on the context of the question. Sometimes the answer depends on who you ask since it may only be an opinion or a feeling. Sometimes the answer is based on a survey, which is a moment in time, and might change a day later. I write a lot about secure mobile access, especially to the enterprise, so I'm obviously interested in any stories about the risks of mobile devices. There were a couple over the last few weeks that really caught my attention since they seemed to completely contradict each other. Earlier in the month, SC Magazine had a story titled, RSA 2013: iOS safer than Android due to open app model, patching delays which covered much of what many already feel - due to Apple's controlled ecosystem, the apps that are available are less of a risk to a user. They made note of the McAfee Threats Report which says Android malware almost doubled from the 2nd to 3rd quarter of 2012. Then just last week, also from SC Magazine, an article titled, Study finds iOS apps to be riskier than Android appeared. What? Wait, I thought they were safer. Well, no apparently. But before I go any further, I do need to mention that the author of both articles, Marcos Colon (@turbomarcos) does reference his first article and says, 'Security concerns surrounding the Android platform have always taken a back seat to that of iOS, but a new study challenges that notion,' so slack has been extended. :-) Anyway, according to an Appthorityreport, iOS apps pose a greater risk and has more privacy issues (to users) than Android. Appthority's 'App Reputation Report' looked at 50 of the top free apps available on both platforms and investigated how their functionality affects user privacy. They looked for “risky” app etiquette like sending data without encryption, sharing information with 3rd-parties, and gaining access to the users' calendars. (Chart) In this particular study, in almost all the cases, iOS gave access to the most info. Of the 50 apps, all of them (100%) sent unencrypted data via iOS but 'only' 92% sent clear text on Android. Tracking user location: 60% on iOS verses 42% on Android. Sharing user data with third-parties: 60% on iOS verses 50% on Android. When it comes to accessing the user's contacts, something we really do not like, 54% of iOS apps accessed the contact list compared to only 20% on Android. One of biggest differences, according to the article, is that at least on Andriod users are presented with a list of content the app wants to hook and the user can decide - on iOS, permissions can be changed once the app is installed. To claim one device is either 'safer,' or 'riskier' is somewhat a moot point these days. Any time you put your entire life on a device and then rely on that device to run your life, there is risk. Any time we freely offer up private information, there is a risk. Any time we rely on others to protect our privacy and provide security, there is a risk. Any time we allow apps access to personal information, there is risk. But like any potential vulnerability, individuals and organizations alike, need to understand the potential risk and determine if it something they can live with. Security is risk management. To top all this off and really what made me write this, was an @GuyKawasaki tweet titled Love Logo Swaps and among the many twists on brands, was this one: And it all made sense. ps Related: RSA 2013: iOS safer than Android due to open app model, patching delays Study finds iOS apps to be riskier than Android Smartphone hacking comes of age, hitting US victims 6 Steps To Address BYOD: A Security Management Roadmap 10 Awesome Logo Swaps Inside Look - F5 Mobile App Manager Is BYO Already D? Will BYOL Cripple BYOD? Freedom vs. Control BYOD–The Hottest Trend or Just the Hottest Term BYOD 2.0 – Moving Beyond MDM with F5 Mobile App Manager Technorati Tags: mobile device,smartphone,ios,android,privacy,safety,security,silva,byod,mam,f5,risk Connect with Peter: Connect with F5:341Views0likes0CommentsWhere Do You Wear Your Malware?
The London Stock Exchange, Android phones and even the impenetrable Mac have all been malware targets recently. If you’re connected to the internet, you are at risk. It is no surprise that the crooks will go after whatever device people are using to conduct their life – mobile for example, along with trying to achieve that great financial heist….’if we can just get this one big score, then we can hang up our botnets and retire!’ Perhaps Homer Simpson said it best, ‘Ooh, Mama! This is finally really happening. After years of disappointment with get-rich-quick schemes, I know I'm gonna get Rich with this scheme...and quick!’ Maybe we call this the Malware Mantra! Malware has been around for a while, has changed and evolved over the years and we seem to have accepted it as part of the landmines we face when navigating the internet. I would guess that we might not even think about malware until it has hit us….which is typical when it comes to things like this. Out of sight, Out of mind. I don’t think ‘absence makes the heart grow fonder’ works with malware. We certainly take measures to guard ourselves, anti-virus/firewall/spoof toolbars/etc, which gives us the feeling of protection and we click away thinking that our sentinels will destroy anything that comes our way. Not always so. It was reported that the London Stock Exchange was delivering malvertising to it’s visitors. The LSE site itself was not infected but the pop-up ads from the site delivered some nice fake warnings saying the computer was infected and in danger. This is huge business for cybercriminals since they insert their code with the third-party advertiser and never need to directly attack the main site. Many sites rely on third-party ads so this is yet another area to be cautious of. One of the things that Web 2.0 brought was the ability to deliver or feed other sites with content. If you use NoScript with Firefox on your favorite news site (or any major site for that matter), you can see the amazing amount of content coming from other sources. Sometimes, 8-10 or more domains are listed as content generators so be very careful as to which ones you allow. With the success of the Android platform, it also becomes a target. This particular mobile malware looks and acts like the actual app. The problem is that it also installs a backdoor to the phone and asks for additional permissions. Once installed, it can connect to a command server and receive instructions; including sending text messages, add URL’s/direct a browser to a site along with installing additional software. The phone becomes part of a botnet. Depending on your contract, all these txt can add up leading to a bill that looks like you just bought a car. In fact, Google has just removed 21 free apps from the Android Market saying its malware designed to get root access to the user’s device. They were all masquerading as legitimate games and utilities. If you got one of these, it’s highly recommended that you simply take your phone back to the carrier and swap it for a new one, since there’s no way of telling what has been compromised. As malware continues to evolve, the mobile threat is not going away. This RSA2011 recap predicts mobile device management as the theme for RSA2012. And in related news, F5 recently released our Edge Portal application for the Android Market – malware free. Up front, I’m not a Mac user. I like them, used them plenty over the years and am not opposed to getting one in the future, just owned Windows devices most of my life. Probably due to the fact that my dad was an IBM’r for 30 years. Late last week, stories started to appear about some beta malware targeting Macs. It is called BlackHole RAT. It is derived from a Windows family of trojans and re-written to target Mac. It is spreading through torrent sites and seems to be a proof-of-concept of what potentially can be accomplished. Reports say that it can do remote control of an infected machine, open web pages, display messages and force re-boots. There is also some disagreement around the web as to the seriousness of the threat but despite that, criminals are trying. Once we all get our IPv6 chips installed in our earlobes and are able to take calls by pulling on our ear, a la Carol Burnett style, I wonder when the first computer to human virus will be reported. The wondering is over, it has already happened. ps Resources: London Stock Exchange site shows malicious adverts When malware messes with the markets Android an emerging target for cyber criminals Google pulls 21 apps in Android malware scare More Android mobile malware surfaces in third-party app repositories Infected Android app runs up big texting bills Ignoring mobile hype? Don't overlook growing mobile device threats "BlackHole" malware, in beta, aims for Mac users Mac Trojan uses Windows backdoor code I'll Believe Mac malware is a problem when I see it BlackHole RAT is Really No Big Deal 20 years of innovative Windows malware Edge Portal application on Android Market311Views0likes0CommentsInvasion of Privacy - Mobile App Infographic Style
Couple blogs/weeks ago, I posted What’s in Your Smartphone? covering the recent Nielsen report, State of the Appnation – A Year of Change and Growth in U.S. Smartphones. According to the study, 70% (last year) and 73% (this year) expressed concern over personal data collection and 55% were cautious about sharing location info via smartphone apps so, obviously, it is important that users are aware of the risks they face when downloading and using apps. So it is perfect timing that I came across Veracode’s infographic showing real world cases to outline the threat to user privacy posed by mobile apps. Infographic by Veracode Application Security Fascinating and scary at the same time. ps References: How Mobile Apps are Invading Your Privacy Infographic Infographic: How Mobile Apps Invade Your Privacy State of the Appnation – A Year of Change and Growth in U.S. Smartphones Nielsen: 1 in 2 own a smartphone, average 41 apps Freedom vs. Control BYOD–The Hottest Trend or Just the Hottest Term Hey You, Get Off-ah My Cloud! Evolving (or not) with Our Devices The New Wallet: Is it Dumb to Carry a Smartphone? BYOD Is Driving IT ‘Crazy,’ Gartner Says Consumerization trend driving IT shops 'crazy,' Gartner analyst says296Views0likes0CommentsAndroid and SSL. What Doesn't Work.
Not so long ago I wrote a blog entry about SSL on Android in regards to some certificates, and mentioned that I would be following up as the work progressed. I have worked through the options and implemented a working solution that I’ll eventually blog about, but this entry is to discuss what doesn’t work, or is a sub-standard solution, what I settled on, and why. It’s light on implementation details, but does offer enough information that interested developers can research a similar solution. The options I discovered or considered are: Forcing the user to import the requisite certs Ignoring all SSL errors Allowing over-ride of errors globally to the app Using the browser to implement exceptions to SSL security Forcing the user to accept problems every time they use the app Creating a system to securely store exception information and use it every time the app loads Many developers adopt the first solution because they have static sites the app is accessing, and can simply say “do this once and you don’t have to worry about it again” (until the cert expires). In the case of the app I’m developing, it is designed for use with scenarios where the certs are often self-signed, and in a testing environment, often transient. So this option was not one I wished to pursue. In the previous blog I mentioned ignoring all SSL errors, and that is a dangerous route I would not ask users to bear. Ignoring errors without asking the user opens users up to Man in the Middle (MitM) attacks. So this one was ruled out from day one – though it appears many developers are going this route. I did briefly consider in the application options giving the user a check-box to silently over-ride SSL errors. Since this is within the control of the user, it was a better solution, but as most of us know, options like this are set once and not looked at again unless there is a problem. And in the case of SSL MitM attacks, it’s too late when you notice a problem. So I ruled this option out also. In that previous blog, I had alluded to what I hoped might be a simple solution to the problem. It was my hope at the time that one could simply call the browser using the Android Dev system of “intents” and ask it to open the page, thus using the browsers’ good certificate error handling to create the exception. Except the default browser on most Android devices does not store exceptions – so there was no way to utilize that information from a remote application. Thus, I dropped this line of enquiry also. It is a relatively easy endeavor to make two dialogs and write a little bit of code to ask the user each time you go out to the web application if they accept the issues with the certificate. One dialog would handle “host name mismatch” exceptions, the other would handle “Certificate Not Trusted” errors – both of which can easily occur in the environment the app will target. I did consider going this route, but the application makes many SOAP calls to the same server over the course of its lifetime, so this would become annoying for users. The only thing worse than having no application is having one that no one wants to use because it’s too painful. So this option was dropped also. This leaves the last option. It is the most involved, requiring both of the dialogs mentioned above, and more code to handle the exceptions. It also requires the exception information be saved… Which then requires that this saved information be encrypted, since it will reside long-term on the device. The solution has the following elements, just for those who are looking into this type of thing: Application level username and password. Java salted encryption of application password. Dialogs to ask user to approve exceptions. An SQLite database of exception information. Java encryption of all information stored in the database. This leaves only one issue – how to “untrust” a site. Since this is not a common problem, I will likely put out version 1.0 with only the option to delete the application user, which in turn will delete all exception information. This may sound extreme, but it is a rare scenario, and I have to leave something for version 2.0. Out now, improved later, in the vein of all current development methodologies. In version 2.0 I’ll allow deletion of individual exception information. But you never know, I may decide to side-track and implement this functionality in version 1.0, depending upon the other portions of the development effort. The information stored in the database is in the form FQDN, username, password. From which the app can then rebuild the SOAP URI. While it wasn’t strictly necessary to encrypt the FQDN, as long as the encryption code was there, why leak information about the network? It added weeks to my development effort to get this up, running, and thoroughly tested, but it was worth it. When a company throws up a test environment and uses a self-signed cert simply because it is easier, the application needs to support that test environment with a minimum of pain. This is a relatively common occurrence in the space the app is in, so it was worth the effort. Your mileage may vary. Now, back to actually communicating with the server and giving users the information/control they want .268Views0likes0Comments