
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
gulp-cdnfailover
Advanced tools
Create html/javascript in an html page that loads a resource with failover
gulp-cdnfailover is a gulp plugin to create HTML snippets that will try to load your JS/CSS sources from CDN locations and if there are any errors, it fails over to local sources. The HTML snippets for javascript are synchronous/blocking where as the CSS snippet will make its best effort to load the local files as quickly as possible.
Install gulp-cdnfailover as a development dependency:
npm install --save-dev gulp-cdnfailover
Add it to your gulpfile.js:
var cdnfailover = require("gulp-cdnfailover");
gulp.src("./src/index.html")
.pipe(cdnfailover({
verbose: true,
localfilesroot: 'resources/', // make sure it ends with a slash
uselocalfilesonly: false,
files: [{ name: 'jquery-slim-min-js',
local: 'js/jquery/dist/jquery.slim.min.js',
cdn: 'https://code.jquery.com/jquery-3.2.1.slim.min.js',
cdnintegrity: 'sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN',
cdncrossorigin: 'anonymous'},
{ name: 'bootstrap-min-css',
local: 'css/bootstrap/dist/css/bootstrap.min.css',
cdn: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
cdnintegrity: 'sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u',
cdncrossorigin: 'anonymous'}]}))
.pipe(gulp.dest("./dist"));
The module looks for <!-- cdnfailover:NAME_OF_ENTRY --> line and replaces with the appropriate snippet. It automatically detects if it is a JS or a CSS resource by checking the extension of the local.
For the example above, your src/index.html should have these lines: <!-- cdnfailover:bootstrap-min-css --> and <!-- cdnfailover:jquery-slim-min-js -->
Example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- cdnfailover:bootstrap-min-css -->
</head>
<body>
<!-- Placed at the end of the document so the pages load faster -->
<!-- cdnfailover:jquery-slim-min-js -->
</body>
</html>
The output will look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"><script>var e=document.styleSheets[document.styleSheets.length-1];if(typeof e==="undefined"||e.href!=="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"||((!e.cssRules||!e.cssRules.length)&&(!e.rules||!e.rules.length)))(function(){var e=document.createElement("link");e.rel="stylesheet",e.href="css/bootstrap/dist/css/bootstrap.min.css",document.head.appendChild(e)})();</script>
</head>
<body>
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous" onerror="(typeof cdnfailover==='undefined')?cdnfailover={_1:true}:cdnfailover._1=true"></script><script>(typeof cdnfailover!== 'undefined')&&cdnfailover.hasOwnProperty(_1)&&document.write('<script src="js/jquery/dist/jquery.slim.min.js"><\/script>');</script>
</body>
</html>
Type: Boolean
If true, log verbose while running.
Type: Boolean
If true, we don't do any of these tricks in this extension. We simply output a
Type: Array
Define entries that will be used to create the HTML snippets
Type: String
Name of the file entry. This name will be used to match a comment line in the source HTML file. This comment line will be replaced with an HTML snippet. The comment line has the format of: <!-- cdnfailover:FILES.NAME -->. For example, if name='bootstrap.min.js', then the comment line should be <!-- cdnfailover:bootstrap.min.js -->
Type: String
This root will be appended to all local files locations. Useful if you are putting all local files under a directory. Defaults to empty string.
Type: String
CDN location of the source.
Type: String
crossOrigin attribute of CDN location of the source.
Type: String
integrity attribute CDN location of the source.
Type: String
Local location of the source.
Example:
{
verbose: true,
files: [{ name: 'jquery-slim-min-js',
local: 'js/jquery/dist/jquery.slim.min.js',
cdn: 'https://code.jquery.com/jquery-3.2.1.slim.min.js',
cdnintegrity: 'sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN',
cdncrossorigin: 'anonymous'}
]
}
We use the following algorithm to detect whether JS or CSS has been successfully downloaded by the browser.
Reach us at Uppercase Brands
FAQs
Create html/javascript in an html page that loads a resource with failover
We found that gulp-cdnfailover demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.