A few days back, we received a priority message in our organization’s Teams chat, which read: Security Vulnerability found – Polyfill JavaScript detected – HIGH.
To give a context, I work for a major banking firm and as you must know, banking and security vulnerabilities are like major foes. So, we started to dig deep into the matter and got it resolved in a few hours, which I’ll discuss in the following. But the good (or worst?) part is when I googled about the issue initially, the search results that popped up kept me hooked for the rest of the day!
Let’s highlight a discrepancy between a modern and a legacy browser. Here’s a comparison of the latest Chrome release versus Internet Explorer (IE) 9. Modern browsers support a whole lot of ES6 features and at the same time, IE9 and also IE11, which are still used by a lot of companies barely support any ES6 features.
Here comes to help the concept of transpiling, which in the context of JavaScript, refers to converting source code written in modern JavaScript (ES6/ES2015 and beyond) into an older version like ES5, which is widely supported by older browsers. A very popular transpiler is Babel, which offers a range of features like syntax transformation, code bundling (along with Webpack) and support for JSX (for our sweet friend, React!).
Now, use of transpilers is very common at places where there is a lot of modern syntax, and one has to ensure the compatibility across different environments. Do note that converting an entire codebase into a different version requires a heck lot of time and also setting up a build process and additional configuration for things like Babel. It goes untold that, along with converting syntactical features, API functionality to extend the same feature replication in old browser is also covered.
Coming to the reference of Babel, it constitutes a lot of packages, providing plugins for different kinds of functionalities like transforming ES6 classes, arrow functions, etc. into equivalent JS code. Among this, it also offers its own “polyfill” package.
Polyfills are pieces of code which enable old browsers to provide the same/almost same JS functionality, which they don’t natively provide, that is shown in newer browser versions. Here’s a quick video example and very simple implementation.
Now one might think, then what’s the difference between transpilers and polyfills? Well, polyfills focus on emulating specific APIs which are missing rather than changing the entire codebase into an old-browser-friendly version done by transpilers. This allows for a more granular approach and of course, making it more efficient and performant.
This should give us enough background to get to the point to why I got hooked for a day till the very moment I’m writing this, about polyfills.
Now, Babel has a package called babel/polyfill which constitutes of 2 libraries: core-js and regenerator-runtime. Initially, importing this package would bring in all the polyfills into action.
import '@babel/polyfill';
But bringing in everything whether your project would use them or not, increased the bundle size and injecting polyfills globally might lead to conflicts in objects.
This led to deprecating the package and Babel recommends using the core-js library directly by
Step 1: Modifying the babel configuration
{ "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 }] ]
}
Step 2: Manually import the polyfills that you’d use in your project
import "core-js/es/array/includes";
import "core-js/es/promise";
thus, saving memory and reducing unnecessary code.
Now, this is the end of one part, not so concerning per se, but definitely important in regard of a project, staying up to date with the changes in dependencies, serving their customers a better experience.
BUT. This is not all.
We’re about to discuss a major attack which took place recently and shook up the entire internet and got them scouring their codebase.
And, it includes the thing which we’ve discussed over here. So stay tuned for the second part!