Nowadays, security has become a really big concern. If you are storing any user data on your servers, you should seriously consider encrypting all communications between your client and server using SSL.
Again, simply using SSL is not enough. There are lots of things people need to understand about SSL before they can assume that their SSL encrypted traffic is safe. One major thing that people need to watch out for is the Man-in-the-middle (MITM) attack. Let me explain how an MITM can be done.
Server ======> Client
SSL
When a client interacts with the server through SSL encryption, all data is exchanged in a form which is not readable by anyone. Say, if a cracker was to listen to an already established SSL session, he will see encrypted data which he can't decrypt. In this case, the communication is fully secure.
But what if the cracker somehow inserts himself in the middle of the client and server even before the SSL connection was established?
Server ======> Cracker ======> Client
SSL SSL
This scenario will mean that the cracker acts as server to the 'Client' and a client to the 'Server'. Thus the cracker can read all data being exchanged without having to bother about breaking the SSL connection. Please note that there still are 2 SSL connections being established, and both these connections are fully secure. But this kind of vulnerability can be exploited if the cracker can hijack the connection before it is established.
In order to prevent this kind of MITM attacks, the SSL certificates are required to be signed by a Certification Authority (CA). Say, a user tries to access data on the encrypted channel. The Server sends a certificate signed by a trusted CA, to the Client, and the Client already having a list of trusted CAs can verify that this certificate is indeed genuine. If a cracker tries to insert himself in the middle, the cracker will have to submit a certificate to the Client, but he can't get it signed by a trusted CA, so the Client will be shown an exception.
Remember, when your browser suddenly shows a warning about an untrusted HTTPS connection, and asks whether you want to add an exception? In devices like Android, the SSL connection will not be established at all, since the certificate was not signed by a trusted CA.
There are various things that we can deduce out of this:
1. This prevents MITM attacks effectively, except in rare cases which I will get to in a short time.
2. If you have a self-signed certificate on your server, then there is no way the Client can know whether he is being a victim of MITM attack or not. (since the cracker in the middle will also have a self-signed certificate). Thus self-signed certificates in production mode are a strict no-no, unless you can send your self-signed certificate to the user in a separate secure channel.
3. If you have a self-signed certificate on the server, and you just want to use in testing mode in your app, your client app will not allow SSL connection to happen.
Particularly, we were faced with the issue that we were trying to run an android app called ODK-collect with a self-signed certificate on the server (for testing). Since android didn't see the certificate as trusted by a CA, it didn't allow the connection to take place. As explained before, this is by design to prevent MITM attacks.
If you are asking why I would like to have self-signed certificate on the server when I previously recommended against it, there can be various reasons for doing that:
1. Maybe you are stuck with talking to a server which uses a self-signed certificate. You have no control over the server but are working on an app that has to talk to this server.
2. You want to test your client-server connection using self-signed certificate. I am not sure if you can obtain a CA signed certificate for hostname as localhost.
3. Even free certificate provider like CAcert may sign your certificate, but CAcert is not treated as trusted CA by most browsers and clients, so they are treated at par with a self-signed certificate.
4. Maybe you just want to avoid the hassle of paying for a CA to sign your certificate, and want to go for self-signed approach.
So, we were trying to find out how to use self-signed certificate and getting ODK-collect (any android app for that matter) to communicate with our server. There are various options available:
1. Trust all certificates
Stack Overflow and other blogs are filled with answers that will allow your app to trust all certificates by default. Even though most answers say that this should only be done in testing mode, what if somebody forgot to turn it off in production mode? In case you are wondering, if your android app trusts all certificates, then your client will never be able to detect MITM attack and will continue to do business as usual. So, in case you want to do it like this, you should exercise extreme caution that this code doesn't go in production. In fact, if running your app with your own self-signed certificates is so easy, why even do this?
2. Install your certificate using SD card method
You can install the certificate using SD card method. If you are testing on a few devices, yes, you could do this. But if you are using this on many devices, there is the problem of having to do this manual method. In case you are going to use self signed certificate in production, you will have to ask all your users to manually install the certificate. Hardly a feasible scenario.
3. Packaging the certificate within your android app and allowing an SSL connection only with the same certificate, disallowing all others
This is the preferred route. What you do is - put the certificate within your apk, change your HTTPS connection to only allow this certificate and discard the rest.
Let me come back to an important issue that I didn't address previously. Say, you have a certificate signed by a trusted CA on the server, you may think that you are now fully secure. But unfortunately, there is a scenario when the cracker could get hold of a fake certificate signed by a trusted CA, and do an MITM. The end-points of the connection channel have no way to know that their traffic is being snooped by the cracker. You think this is highly unlikely? What if the cracker turns out to be an influential organization like the NSA?
Read this: https://www.schneier.com/blog/archives/2013/09/new_nsa_leak_sh.html
You may say that NSA is a spying agency that is trying to protect American interests. But what if there was some spurious government organization that uses its own influence to make some trusted CA sign their fake certificates? Definitely possible. Worst part is, there is not much you can do to prevent such kind of an attack. This is precisely why people like Schneier are saying that the Internet is broken.
But if your android app only accepts your self-signed certificate, and not even certificates from a trusted CA, then this kind of influential attack can be prevented, since you are only allowing your own certificate for communication, nothing else. Note that the certificate has to reach the user in a safe and secure manner, in this case, packaged within the android package (.apk). Another note: you have to ensure that when the user downloads your apk, it is not changed in transit by a cracker (use checksums etc. to verify the downloaded apk). We are currently using this methodology for our new product called Form Factor.
Enough been said. In my next blog post, I will talk about what code you need to write to get this done. This will not only apply to ODK-collect, but any android application where you want to get running with self-signed certificate on your server.
Tuesday, February 4, 2014
Sunday, June 3, 2012
Review of DOMO Slate X3D
I was recently looking for a tablet and after looking at some reviews, I decided to buy DOMO Slate X3D. Still I was dissatisfied with the fact that there aren't any comprehensive reviews for this tablet. So I thought, I should take the plunge and help people out in making the decision whether this is the one to buy or not.
First impression - the tablet, in terms of build quality looks okayish, but obviously it can't matchup to the iPad and Samsung galaxy tab lookswise. The tablet is a bit thick, reminds me of the old samsung galaxy tab.
The biggest turn down for the tablet is its screen. It doesn't look very pretty, and the reason for that is the colors. Unlike other smart phones and tablets which come with 16 million colors, this has less colors, and it is not specified. But let me take a guess - 256k colors? The screen is also a bit too wide making movies appear a little skewed, and browser in landscape mode leaves less space for viewing, especially when you have the virtual keyboard coming up.
Nowadays most cheap and low end tablets come with resistive touch screens. I have used resistive touch and am convinced that resistive touch is really crappy. So what I say is - if you are tempted to save money by going for a resistive touch screen, please 'resist' that temptation. It is just not worth saving the extra money. This tablet thankfully has capacitive touch, and it is actually good, almost unexpected after the initial disappointment. The virtual keyboard is really excellent to use, and no touch on any keys is lost - a good typing experience and excellent capacitive touch here.
I tested out the sound card and compared the sound with my other devices like laptop, smart phone and my take is that sound card is exceptionally good, with very good loudness and decent sound quality too. Mind you, I am talking about the output to my head phones, and not the built in speakers. The built in speakers, sadly, are not very loud and are a bit disappointing.
This tab has a front facing camera, appropriate for skype video chats or video conferencing. The camera is good. It takes photos with resolution 640x480 (It is .3 MP camera, a spec that they have not specified anywhere)
On the other hand, the mic is very disappointing. I downloaded some recording software and tried recording, and the mic doesn't register any sound unless you put it very close to your mouth. What this means is - the tablet can't properly be used for skype calls because of poor mic.
OK, this is a gaming tablet, so I got to talk about games as well. I am not much of a gamer, but I don't mind the occasional hurling birds at pigs or slicing some fruits. I also tried a car race on the tablet which came pre-installed. And my take on games is - this tablet really lives upto expectations. There is no lag, the extra graphics processor comes into play and the gaming experience is very nice.
I downloaded adobe pdf viewer on the tab, and opened some comics and was satisfied with the way it rendered them. So this is a good device for reading books and articles.
Battery is nice, gives a decent backup of 5-6 hours as specified, on continuous usage, enough for me who is going to use this tablet mainly at home, not far from a power outlet.
This tablet has the latest android OS, and it comes pre-rooted too. That may not mean much to a normal user, but to a developer that is added convenience. Even if you are not a developer, you are still in advantage because you have many benefits of rooting like ability to make complete backups, and many useful things that a rooted device can do which a non-rooted device can't. Not to say that it is difficult to root a device like Samsung tab, but still, you stand the risk of losing your warranty from the manufacturer if you root, which is not the case here, since the manufacturer himself rooted the device for the user.
I tested times for shutting down and starting up the tablet. It shuts down in a real quick 2-3 seconds, and takes just over a minute to do a complete start of the Android OS.
512 mb ram, 4 gb internal memory is enough to run any app and install as many apps as anybody wants without worrying about space limitations. Not to forget that you can easily add an extra sd card and increase storage space.
This device comes with only a charger, no cables to connect to pc or usb drive (meaning you have to buy them separately). But considering the cost of the device, I am not complaining.
This tablet may be one of the rare ones that is cheap as well as good. Apart from the screen which should have been 16 million colors, and a poor mic, everything is awesome and for a tablet of around 8k range, this is an excellent buy. But I would like to add that if you are not on a very tight budget, do look at Samsung tab 2, which has more features, better build quality, beautiful screen and everything good and prices are expected to goto to about 15-16k soon.
Tuesday, November 22, 2011
New localstorage based database API
We were initially working on Firefox 4.0 and Indexed DB, and I thought of writing some tips and tricks on getting it working. It turns out that Indexed DB is not yet supported on Android browsers and iPhone browser, which is a shame, because we want to run our web-app throughout the whole ecosystem of devices that are now available in the market.
Most browsers support a basic subset of HTML5 standards. But Indexed DB, surprisingly, is not yet heavily adopted. So we were faced with the dilemma of how should we get our app running on Linux, Windows, Mac, iOS, Android etc.
We looked at Web database and Indexed DB, both of which have serious limitations, as of now. So I decided that something had to be done. And I clicked upon a great idea of writing my own API for storage, that works on localstorage.
Now local storage is being supported by all browsers. But it is a very simplistic approach of storing client side data in key-value pairs. This means that you can probably store a To-do list using it, but you may not find it convenient for having something like an electronic data-collection app storing electronic forms, data filled in for the forms, users, settings all in local storage. All this complexity needs a database like storage and organization in form of object stores or tables.
So the local storage API came into being. What it does is - it is just a layer above the localstorage of the browser, so that a developer can write statements to create a table, add columns, add records, retrieve records, search on the records, drop tables, drop full database and more. The API actually stores all data in certain specific key formats so that organization is possible and the API can easily do the operations required by the developer.
The advantages of this approach are manifold, some of which were already mentioned, but here they are again:
1. Requires local storage to be working on the browser, something that's supported on all major browsers right now, including mobile phone browsers.
2. Local storage is synchronous in nature. I am not sure since this could be a disadvantage for some, since they may be looking at asynchronous operations. But the thing is, our app needed synchronous operation, and it much easier to write code with synchronous requests.
3. Is somewhat like Indexed DB in implementation, no sql knowledge is needed.
4. Fairly easy to use the API
For more details and for downloading it, please go to:
https://code.google.com/p/gwt-localstorage-db/
Most browsers support a basic subset of HTML5 standards. But Indexed DB, surprisingly, is not yet heavily adopted. So we were faced with the dilemma of how should we get our app running on Linux, Windows, Mac, iOS, Android etc.
We looked at Web database and Indexed DB, both of which have serious limitations, as of now. So I decided that something had to be done. And I clicked upon a great idea of writing my own API for storage, that works on localstorage.
Now local storage is being supported by all browsers. But it is a very simplistic approach of storing client side data in key-value pairs. This means that you can probably store a To-do list using it, but you may not find it convenient for having something like an electronic data-collection app storing electronic forms, data filled in for the forms, users, settings all in local storage. All this complexity needs a database like storage and organization in form of object stores or tables.
So the local storage API came into being. What it does is - it is just a layer above the localstorage of the browser, so that a developer can write statements to create a table, add columns, add records, retrieve records, search on the records, drop tables, drop full database and more. The API actually stores all data in certain specific key formats so that organization is possible and the API can easily do the operations required by the developer.
The advantages of this approach are manifold, some of which were already mentioned, but here they are again:
1. Requires local storage to be working on the browser, something that's supported on all major browsers right now, including mobile phone browsers.
2. Local storage is synchronous in nature. I am not sure since this could be a disadvantage for some, since they may be looking at asynchronous operations. But the thing is, our app needed synchronous operation, and it much easier to write code with synchronous requests.
3. Is somewhat like Indexed DB in implementation, no sql knowledge is needed.
4. Fairly easy to use the API
For more details and for downloading it, please go to:
https://code.google.com/p/gwt-localstorage-db/
Thursday, May 19, 2011
Indexed DB tips and tricks (For Firefox 4)
In these days, webapps are becoming more and more popular and we have a strong case for webapps to replace even desktop apps. For one, webapps run the same way on different operating systems. They just need a browser for running.
After coming up of HTML5 spec, we are looking at really powerful webapps which can have the ability to work offline. Different browsers try to implement HTML5 in their own manner, which is a problem for developers. Especially, since HTML5 is new, there are lot of uncertainties in this area.
One important thing I came across recently is the Indexed DB spec that Firefix 4 and other browsers are implementing. They have made a big change from the Gears implementation (Sqlite) as well as the WebSQL implementation (Sqlite again). Sometimes it is difficult to find proper documentation in this regard.
Since we are currently working on getting IndexedDB working on Firefox 4, we went through a lot of Mozilla documentation and found out that it is quite confusing for a person to understand IndexedDB API.
So I thought that I should share my experiences in this regard, and give some tips and tricks, and some sample code on how to get started.
1. First thing first, let me give you the correct links for the documentation:
https://developer.mozilla.org/en/IndexedDB/IndexedDB_primer
This is an excellent IndexedDB primer from the Mozilla team. It also gives links to other important documentation like the Mozilla IndexedDB API and W3 spec.
Other documentation found on sites like HTML5 rocks etc. sadly don't work on Mozilla Firefox4.
http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/
This is also grossly outdated, and I wasted a lot of my precious time in trying to run the code given here.
2. Note that creating or opening a db on the Firefox 4 has a little different way of doing it. You write a call through mozIndexedDB, not window.indexedDB
To do error handling at one place, so that you don't have to do it repeatedly, you can include this code in the onsuccess() method for opened db.
3. When you try to run IndexedDB through java script embedded in a local HTML file, you will get nasty errors : errors of type unknown and it won't work whatever you do. But if you put in on a web server, then the same html file works and your IndexedDB will be happily created.
One way to create local IndexedDB so that you can test out your applications is: we created a GWT project, and put all our JavaScript code inside a script called from the HTML file inside the GWT project. Then we ran the GWT project and sure enough, it worked well. (I have to say here that I have been working on Java and GWT for quite some time, and am relatively new to JS and JSNI)
4. On Firefox4, if you want to debug your JavaScript code, you need to goto
Tools->Web Console
and this should bring up the web console where you get all the error messages.
5. We tried writing all IndexedDB code as a JSNI function inside our Java classes (since we are coding in GWT or Java), and we had lot of problems in certain JS commands like delete or const. So there is a very simple way to include your IndexedDB code as JS script and still access it from your Java code. Let me give you short steps on how to do that:
First, write all your JS script files inside the main HTML file or access it there using something like:
<script type="text/javascript" src="createDB.js">
</script>
where createDB.js contains the code for creating database and objectStores (say there is a function called createDB() inside the .js)
Now you can easily access this file from your HTML file, by just including the following code:
<script type="text/javascript">
createDB();
</script>
Ah, but this is not very impressive, since we want to access this function inside your Java class, not through your HTML file. So, in order to do that, you do something like this in your Java file:
public void onModuleLoad() {
createDb();
}
public native void createDb() /*-{
$wnd.createDB();
}-*/;
And voila, you have all functions defined inside .js file accessible through JSNI in your GWT java file.
You can pass objects from Java to JS, JS to Java etc. without any problems from now on.
6. An important thing to note is that you will have to open the database every time you want to do a transaction on the Indexed DB. It seems like that the db closes itself once you are done with the transaction and you have no more code for it in that particular function. This is a bit annoying since it increases the size of your code, but my guess is that this was deliberately done to prevent memory leakages or having unsaved changes on the db.
7. In case you were wondering how to specify an object store with autoIncrement as true, here is some sample code:
8. Some people may tell you that the 'put' function is something like the 'add' function for adding the data to the Indexed DB. That is a misconception, since 'put' has some very important differences that should be carefully noted.
What they tell you is that you can use 'put' function to either add or replace a record in the db. But what they don't tell you is that 'put' function needs the Primary key as an input for it to work.
Let me explain by example. If suppose, your object store(table) had an auto increment key as Sno and a data column called Name.
In order to use the add function, you can just specify Name to the function and it will auto-generate the key by itself. But if you use the 'put' function here, it won't work and it will show an error. And that goes for even if the Name you specified is already existing. For doing a put, you will have to specify the key. So, if you really want to auto generate the key, you have no option but to use the 'add' function, and if you want to edit certain location, then you have to do a search and find what is the key for that particular data, and then pass it on the 'put' function.
Yes, I know this is going to make your code longer, but I don't think there is any other method to doing this. If you have a situation when you don't know whether you have to do an 'add' or a 'put', then you have to first search for a particular index, if found, do a 'put' at the found key, else do an 'add'.
After coming up of HTML5 spec, we are looking at really powerful webapps which can have the ability to work offline. Different browsers try to implement HTML5 in their own manner, which is a problem for developers. Especially, since HTML5 is new, there are lot of uncertainties in this area.
One important thing I came across recently is the Indexed DB spec that Firefix 4 and other browsers are implementing. They have made a big change from the Gears implementation (Sqlite) as well as the WebSQL implementation (Sqlite again). Sometimes it is difficult to find proper documentation in this regard.
Since we are currently working on getting IndexedDB working on Firefox 4, we went through a lot of Mozilla documentation and found out that it is quite confusing for a person to understand IndexedDB API.
So I thought that I should share my experiences in this regard, and give some tips and tricks, and some sample code on how to get started.
1. First thing first, let me give you the correct links for the documentation:
https://developer.mozilla.org/en/IndexedDB/IndexedDB_primer
This is an excellent IndexedDB primer from the Mozilla team. It also gives links to other important documentation like the Mozilla IndexedDB API and W3 spec.
Other documentation found on sites like HTML5 rocks etc. sadly don't work on Mozilla Firefox4.
http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/
This is also grossly outdated, and I wasted a lot of my precious time in trying to run the code given here.
2. Note that creating or opening a db on the Firefox 4 has a little different way of doing it. You write a call through mozIndexedDB, not window.indexedDB
var
request = mozIndexedDB.open(
"MyTestDatabase"
);
To do error handling at one place, so that you don't have to do it repeatedly, you can include this code in the onsuccess() method for opened db.
db.onerror = function(event) {
// Generic error handler for all errors targeted at this database's
// requests!
alert("Database error: " + event.target.errorCode);
};
One way to create local IndexedDB so that you can test out your applications is: we created a GWT project, and put all our JavaScript code inside a script called from the HTML file inside the GWT project. Then we ran the GWT project and sure enough, it worked well. (I have to say here that I have been working on Java and GWT for quite some time, and am relatively new to JS and JSNI)
4. On Firefox4, if you want to debug your JavaScript code, you need to goto
Tools->Web Console
and this should bring up the web console where you get all the error messages.
5. We tried writing all IndexedDB code as a JSNI function inside our Java classes (since we are coding in GWT or Java), and we had lot of problems in certain JS commands like delete or const. So there is a very simple way to include your IndexedDB code as JS script and still access it from your Java code. Let me give you short steps on how to do that:
First, write all your JS script files inside the main HTML file or access it there using something like:
<script type="text/javascript" src="createDB.js">
</script>
where createDB.js contains the code for creating database and objectStores (say there is a function called createDB() inside the .js)
Now you can easily access this file from your HTML file, by just including the following code:
<script type="text/javascript">
createDB();
</script>
Ah, but this is not very impressive, since we want to access this function inside your Java class, not through your HTML file. So, in order to do that, you do something like this in your Java file:
public void onModuleLoad() {
createDb();
}
public native void createDb() /*-{
$wnd.createDB();
}-*/;
And voila, you have all functions defined inside .js file accessible through JSNI in your GWT java file.
You can pass objects from Java to JS, JS to Java etc. without any problems from now on.
6. An important thing to note is that you will have to open the database every time you want to do a transaction on the Indexed DB. It seems like that the db closes itself once you are done with the transaction and you have no more code for it in that particular function. This is a bit annoying since it increases the size of your code, but my guess is that this was deliberately done to prevent memory leakages or having unsaved changes on the db.
7. In case you were wondering how to specify an object store with autoIncrement as true, here is some sample code:
var user_form = db.createObjectStore("user_form", {keyPath: "user_form_id", autoIncrement: true} );
Then you can create indexes inside the createIndex command like this:
user_form.createIndex("name", "name", { unique: false });
unique:true will make the column as a unique column type, so that it is always unique.
8. Some people may tell you that the 'put' function is something like the 'add' function for adding the data to the Indexed DB. That is a misconception, since 'put' has some very important differences that should be carefully noted.
What they tell you is that you can use 'put' function to either add or replace a record in the db. But what they don't tell you is that 'put' function needs the Primary key as an input for it to work.
Let me explain by example. If suppose, your object store(table) had an auto increment key as Sno and a data column called Name.
In order to use the add function, you can just specify Name to the function and it will auto-generate the key by itself. But if you use the 'put' function here, it won't work and it will show an error. And that goes for even if the Name you specified is already existing. For doing a put, you will have to specify the key. So, if you really want to auto generate the key, you have no option but to use the 'add' function, and if you want to edit certain location, then you have to do a search and find what is the key for that particular data, and then pass it on the 'put' function.
Yes, I know this is going to make your code longer, but I don't think there is any other method to doing this. If you have a situation when you don't know whether you have to do an 'add' or a 'put', then you have to first search for a particular index, if found, do a 'put' at the found key, else do an 'add'.
That's it for now. I will keep on updating with more tips and tricks as I learn more while getting the Indexed DB working on FF.
Subscribe to:
Posts (Atom)