Friday, June 27, 2014

Week 7

The chrome extension supports <iframe> tags with the 'src' attribute pointing to a gnocchi file on the server now. Also, I change the way the browser interprets a gnocchi file to prevent the possible code injection attack. Rather than "text/html", the modified content-type of a gnocchi file is "text/plain", so all the injected codes would be regarded as just plain text by the chrome browser.

To resolve the <iframe> reference, I add two listeners: one is added on the event "chrome.webRequest.onHeadersReceived", which is fired when the request header is received to check for gnocchi files, and the other one is added on the event "chrome.webNavigation.onCompleted", which is fired when the document resources are completely loaded and initialized.

For now, I'm using a global variable to record the urls of the gnocchi files. I know that using global variables is not a good practice in coding, but it seems to me that it is the best solution. Alternatives are message sending and local storage. Message sending is more tedious and turning the code even less readable than global variables. Besides, I have no idea how to embed a listener on the event "chrome.webNavigation.onCompleted" inside another listener on the event of receiving message at this point. Anyway, I will manage message sending to see how well it works if I have time. As for local storage, that is a inferior choice considering the performance of the extension. Also, local storage runs asynchronously, competition between different processes makes the extension less reliable.

Here is the result of the test case with 20 <iframe> tags in a webpage (some of them are not visible due to the limited size):

Key management on the client side is my next step. I will take a look at google's e2e library to learn more about how they manage it. Furthermore, message sending between different listeners of the extension is also in my plan so as to get rid of annoying global variables.

Friday, June 20, 2014

Week 6

I removed redirection from the chrome extension this week, and did some research on the chrome file system.

First thanks go to Olga for inspiring me to find a way to circumvent redirection. Here is how it goes. The chrome extension checks the response headers to detect gnocchi files, as I mentioned before. If a gnocchi encryption or signature file is to be received, the extension will modify the headers so that the browser would process the response body as with content-type "text/html", rather than "multipart/signed" or "multipart/encrypted". In this way, an associated DOM document is created, whose content is the data received from the server. After the content is loaded, the extension injects codes to replace the encrypted message obtained from the server with the corresponding decrypted message.

Here is a possible attack I come up with. Since the DOM document is first loaded with the data from the server as its content. Is it possible for a malicious attacker to inject codes by sending them as the encrypted data?

As for the file system, fortunately, google provides an API named "goog.fs" for temporarily storing some files locally. What's more, "goog.fs" tends to work asynchronously, which is a piece of good news for the extension's performance. With a workable file system, I am going to solve the <iframe> src reference as follows. The extension would detect the web requests. And if a request to a gnocchi file is detected, the extension would make a XMLHttpRequest to retrieve the encrypted message first, decrypt it, store the decrypted message locally using the file system, and finally modify the src attribute in the <iframe> tags to reference to the local decrypted files.

Next week, I mean, in the near future (why should I say "next week", if, as a matter of fact, I am not finishing the tasks next week?), I am going to resolve the <iframe> src reference and take a look at how google's e2e library manage their key storage. Hopefully, google's method is helpful for me to figure a way for key management in the chrome extension.

Friday, June 13, 2014

Week 5

The chrome extension performs basic AES decryption now. The data are in three different encoding formats:

  • Base64, for retrieving from the server
  • Byte arrays, for decryption
  • Text string, for displaying

We adopt the AES algorithm in CBC mode for decryption and encryption. The following is the data retrieved from the server:

Since we do not have mechanism for key distribution now, the decryption key is included in the data, the shorter base64 string. The key length indicates that the encryption algorithm is AES128. Also, the initialization vector (iv) for CBC decryption is included in the ciphertext, the longer base64 string, as the first 16 bytes. Knowing the key and the iv, we can obtain the plaintext by decryption.
The plaintext includes the message, "Hello Secret world!" and the corresponding signature in RSA scheme.

I also managed to come up with a way for key management and storage on the client side. Because it is generally considered not possible to use file systems on the browser-side in JavaScript (see http://stackoverflow.com/questions/585234/how-to-read-and-write-into-file-using-javascript), I have to use the not-so-secure chrome.storage API.

To ensure security, the following is a preliminary idea to encrypt the keys stored on the extension. Every user creates a user name and the associated password. All the keys are stored encrypted using AES with the hash value of the password as the key. To verify the user, another pair of plaintext and ciphertext is stored with the plaintext randomly generated. Thus, only the encrypted keys and a pair of plaintext and cipher text are stored. In order to check whether a user enters the correct password, we only have to take the hash value of the input, use it as the key to decrypt the ciphertext, and check whether the resulted plaintext matches the one stored on the extension.

For next week, I will try to do more research on this problem: how to store keys securely with storage that the attackers may have access to. Also, I will implement the idea above or some other solutions to solve the problem.

Friday, June 6, 2014

Week 4

"Redirection" was implemented and the end-to-end (e2e) google crypto library in javascript was imported this week.

The quotation make in "Redirection" indicates that it is in fact not real redirection. It works as follows. Once the extension detects a gnocchi file to be received from the server, it opens a new tab in the browser, displays the content (encrypted message for now, since I don't have time to work more on the crypto part), and closes the original tab. I had tried to realize the real redirection, but there seemed to be a bug in chrome. When I tried to access a gnocchi file from a loaded tab, a tab loaded with contents from other links, it got redirected to "about:blank", although the extension worked well in the case of a blank tab, or a newly-opened tab. Please see https://code.google.com/p/chromium/issues/detail?id=300685 for more information related to this issue. (Update before Friday night: I have just fixed the issue. It is now real redirection to the file content, instead of about:blank)

I also included the end-to-end (e2e) google crypto library in the project. It is well-known that there is few reliable crypto library implemented in javascript. I took a look at crypto-js (a nice one with friendly interface, also easy to import), and SJCL (started by people at Stanford University). However, due to the inactivity of both libraries, I selected e2e at last. Though newly developed, e2e is maintained and updated by the developers at Google. Besides, it is relatively easy to import e2e using Google's Closure Library. Finally, Google knows chrome best, so e2e is expected to be compatible with chrome.

I will focus on the crypto part of the project next week, in order to have decryption work. Also, if I have time, I am going to do more research on file IO in javascript, too. I slow down my research on that because we are mainly handling text message and html document at this moment, and file IO will be an extra feature in the future, rather than the goal at present. Furthermore, file IO is very very tricky in javascript...