The web runs on JavaScript. In fact, some sources suggest that about 74% of all websites use some form of JavaScript library. The number of libraries for JavaScript applications has increased considerably over the last few years. When multiple JavaScript libraries are used together in a web application, they all share the same global namespace called window. Sharing and writing to the same global namespace can lead to unexpected scenarios.

As an example, consider the following two libraries Strophe.js and JSEncrypt.js :

1
2
3
4
5
6
7
8
9
    // Strophe.js
    window.Base64 = {
      encode: function(b) {
      /* code */
      }
      decode: function(b) {
      /* code */
      }
    };
1
2
3
4
5
6
7
8
9
    // JSEncrypt.js
    window.Base64 = {
      unarmor: function(t) {
      /* code */
      }
      decode: function(i) {
      /* code */
      }
    };

Both libraries write to the same global variable Base64. If these libraries are included together, the library that is included last will overwrite the Base64 implementation of the other. This can potentially lead to unexpected situations (we call them conflicts) for unsuspecting developers using both of these libraries together. This can be verified by the following client that tries to encrypt some data using JSEncrypt.

1
2
3
4
5
6
7
 
jsEncrypt = new JSEncrypt();
jsEncrypt.setKey(...);
 
// Returns false instead of encrypted data when Strophe.js is loaded 
// after JSEncrypt.js.
jsEncrypt.encrypt(...);

When the client is executed while only including JSEncrypt then the data gets correctly encrypted but when executing the client after first loading JSEncrypt.js and then Strophe.js, the last call simply returns false.

ConflictJS is an approach to detect conflicting libraries by synthesizing such clients. The approach first dynamically analyzes individual libraries to detect writes to the global namespace while loading a library. Next, each global variable shared by multiple libraries is recorded as potentially conflicting. From the set of potentially conflicting libraries, the approach finally validates the conflicts by synthesizing a client while including the libraries by checking if it really leads to unexpected behavior.

We have evaluated ConflictJS on 951 real-world libraries and the approach finds 166 (17%) certainly conflicting libraries. We envision that ConflictJS helps library developers to prevent conflicts by making informed decisions about the choice of global variables.

If you find our work interesting, you may go through the complete paper by following this link.
We have made our approach open source https://github.com/sola-da/ConflictJS and would welcome you to use it and provide us feedbacks and criticisms.

Featured image from https://commons.wikimedia.org/wiki/File:Tournament_bavarian_engraving.png

Share This