How VIP Mitigated the Impact of Polyfill.io Malware
When a widely-used, free CDN used by up to 4% of the web changes hands and begins serving malicious code to visitors, it’s a bad day.
Earlier this year, the GitHub account and domain for Polyfill.js / polyfill.io were transferred to a Chinese company named Funnull and the CDN service has since been discovered to be serving malware to unsuspecting visitors.
At WordPress VIP, the security of our customers and visitors to our platform is a top concern. So when we learned of Sansec’s discovery of malware served by polyfill.io, our security team sprang into action to mitigate the risk to applications on the VIP platform.
About Polyfill.js
Polyfill.js is a widely used JavaScript library that smooths over differences between older browsers and their modern counterparts. It does this by adding polyfills for newer APIs that may be missing in outdated browsers and devices.
Polyfill.io arose as a CDN to calculate and serve this JavaScript. When embedded on a website, the polyfill.io service detects which browser the visitor is running and serves them a JS file containing the shims necessary to match functionality provided by modern browsers.
In today’s landscape, the need for these shims is very low. All major browsers automatically update to the latest version, and in general they all implement the same standard APIs (with some variation as new standards are proposed and stabilized). All this makes shims like Polyfill.js far less useful, if at all.
Detection, action, and remedy
After Sansec discovered the polyfill.io CDN was being used to serve malicious payloads to unsuspecting visitors, WordPress VIP immediately began assessing the impact to our customers and identifying mitigations.
First, we learned that of those customers leveraging the polyfill.io service, implementations were split 50/50 between using the WordPress Asset Enqueue APIs (like wp_enqueue_script() and wp_register_script()) and hardcoded references.
WordPress’s robust hooks and filters system allowed us to develop a platform-wide patch that detects enqueued scripts loading from cdn.polyfill.io or polyfill.io and dequeues them.
function vip_disallow_polyfill_io_script() {
global $wp_scripts;
$polyfill_host = 'polyfill.io';
foreach ( $wp_scripts->registered as $handle => $script ) {
if ( isset( $script->src ) && false === str_contains( $script->src, $polyfill_host ) ) {
continue;
}
$parsed_url = wp_parse_url( $script->src );
if ( isset( $parsed_url['host'] ) &&
( $parsed_url['host'] === $polyfill_host || $parsed_url['host'] === 'cdn.' . $polyfill_host ) ) {
wp_dequeue_script( $handle );
}
}
}
add_action( 'wp_print_scripts', 'vip_disallow_polyfill_io_script', PHP_INT_MAX );
We chose to dequeue the script across-the-board to ensure the safety of our customers and visitors.
We also considered automatically rewriting the urls to use either the Cloudflare or Fastly replacement CDNs. We opted not to do this because we wanted to leave the decision of adding a new 3rd-party dependency up to customers and there was a low risk of visitor impact, as most browsers no longer need Polyfill.js anyway.
A final word
The Polyfill.js case is a stark reminder about the dangers of supply-chain attacks on the modern web. Third-party dependencies and vendors must be carefully chosen and reviewed on a regular basis. What’s safe today can be tomorrow’s attack-vector and organizations must remain vigilant to limit supply-chain risks.
For more information on supply-chain attack mitigation, we recommend the following resources: Defending Against Software Supply Chain Attacks from CISA and NIST
Supply Chain Attacks: Impact, Examples, and 6 Preventive Measures from HackerOne.
And for general information on raising your WordPress site security, check out our Avoiding CMS Disaster Security Guide.
Author
Nick Daugherty
Staff Engineer, WordPress VIP