Before coming to the actual problem let’s start with a very basic question in web development.
How do you update a specific section of a webpage without reloading the whole page?
Yes, you guessed it right, by making an Ajax request to the server.
In most of the projects at the start of my developer journey I always used jQuery. An Ajax request for me was a call to the ajax function
$.ajax({ url: “…” }) or jQuery.ajax({ url: “…” })
After some time I started using axios, which is another JS library to make a HTTP request to the server.
Both the libraries contains functions that abstracts over the XmlHttpRequest object.
When you make a call with jQuery.ajax() method or axios.get() method, under the hood it creates a XmlHttpRequest object and use its methods open and send.
A quick demo of how the request is sent by these libraries:
Now getting to the actual problem
We are using a library called floweditor in Glific (an open source project in React and Elixir). The library makes some Ajax requests to the backend for its working.
These requests were open and did not have an authentication mechanism. If someone knows the URL and the format of data to send, they can easily make a request to modify the data.
This was a great security concern for us. While the whole application uses a token based authentication system (sending an authorization header in all requests to verify the user), the floweditor library calls were unauthenticated.
The problem: How to add authorization header to the requests from the floweditor library
The library uses axios to send all requests. After going through the documentation of axios we found that it has an interceptor method which can intercept all requests and add additional data.
We tried the interceptor method but it did not work since that needs to be initialized within the library.
Finally we reached to the prototype solution
We knew that the axios request is creating an XHR object under the hood. So why not intercept that!
JavaScript is an object-based language based on prototypes, rather than being class-based.
By knowing the XMLhttpRequest object and its prototype methods we can modify and use it to intercept the request. Since the actual call is made after the send method gets invoked, we modified its prototype to add the authorization header.
We added the header, using the setRequestHeader method provided by the XHR object.
This way we finally resolved the security issue in our project.