Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scan for vulnerable JS Libraries #2372

Merged
merged 62 commits into from
Sep 29, 2017
Merged

Scan for vulnerable JS Libraries #2372

merged 62 commits into from
Sep 29, 2017

Conversation

tkadlec
Copy link
Contributor

@tkadlec tkadlec commented May 26, 2017

Fixes #1948

Uses https://github.com/johnmichel/Library-Detector-for-Chrome and Snyk to check a page for JS libraries with known vulnerabilities.

A few things that still need to be done for this to ship.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is huge @tkadlec thanks so much for putting this together!! 🎉 🔐

const npmMapper = {"GWT":{"url":"http://www.gwtproject.org/"},"Ink":{"url":"http://ink.sapo.pt/"},"Vaadin":{"url":"http://vaadin.com/home"},"Bootstrap":{"url":"http://getbootstrap.com/","npmPkgName":"bootstrap"},"Zurb":{"url":"http://foundation.zurb.com/","npmPkgName":"foundation-sites"},"Polymer":{"url":"http://www.polymer-project.org/","npmPkgName":"@polymer/polymer"},"Highcharts":{"url":"http://www.highcharts.com","npmPkgName":"highcharts"},"InfoVis":{"url":"http://philogb.github.com/jit/"},"FlotCharts":{"url":"http://www.flotcharts.org/","npmPkgName":"flot"},"Blackbird":{"url":"http://www.gscottolson.com/blackbirdjs/"},"CreateJS":{"url":"http://createjs.com/#!/CreateJS","npmPkgName":"createjs"},"Google Maps":{"url":"https://developers.google.com/maps/"},"jQuery":{"url":"http://jquery.com","npmPkgName":"jquery"},"jQuery UI":{"url":"http://jqueryui.com","npmPkgName":"jquery-ui"},"Dojo":{"url":"http://dojotoolkit.org","npmPkgName":"dojo"},"Prototype":{"url":"http://prototypejs.org"},"Scriptaculous":{"url":"http://script.aculo.us"},"MooTools":{"url":"http://mootools.net"},"Spry":{"url":"http://labs.adobe.com/technologies/spry"},"YUI 2":{"url":"http://developer.yahoo.com/yui/2/"},"YUI 3":{"url":"http://yuilibrary.com/","npmPkgName":"yui"},"Qooxdoo":{"url":"http://qooxdoo.org","npmPkgName":"qooxdoo"},"Ext JS":{"url":"http://www.sencha.com/products/extjs"},"base2":{"url":"http://code.google.com/p/base2"},"Closure Library":{"url":"https://developers.google.com/closure/library","npmPkgName":"google-closure-library"},"Raphaël":{"url":"http://dmitrybaranovskiy.github.io/raphael"},"React":{"url":"http://facebook.github.io/react/","npmPkgName":"react"},"Modernizr":{"url":"http://www.modernizr.com","npmPkgName":"modernizr"},"Processing.js":{"url":"http://processingjs.org","npmPkgName":"processing-js"},"Backbone":{"url":"http://backbonejs.org/","npmPkgName":"backbone"},"Leaflet":{"url":"http://leafletjs.com","npmPkgName":"leaflet"},"Mapbox":{"url":"http://mapbox.com","npmPkgName":"mapbox-gl"},"Lo-Dash":{"url":"http://lodash.com/","npmPkgName":"lodash"},"Underscore":{"url":"http://underscorejs.org/","npmPkgName":"underscore"},"Sammy":{"url":"http://sammyjs.org"},"Rico":{"url":"http://openrico.sourceforge.net/examples/index.html"},"MochiKit":{"url":"https://mochi.github.io/mochikit/"},"gRaphaël":{"url":"http://g.raphaeljs.com"},"Glow":{"url":"http://www.bbc.co.uk/glow"},"Socket.IO":{"url":"http://socket.io","npmPkgName":"socket.io"},"Mustache":{"url":"http://mustache.github.com","npmPkgName":"mustache"},"Fabric.js":{"url":"http://fabricjs.com/","npmPkgName":"fabric"},"FuseJS":{"url":"http://kiro.me/projects/fuse.html","npmPkgName":"fuse.js"},"Tween.js":{"url":"https://github.com/sole/tween.js","npmPkgName":"tween.js"},"SproutCore":{"url":"http://www.sproutcore.com"},"Zepto.js":{"url":"http://zeptojs.com","npmPkgName":"zepto"},"three.js":{"url":"http://threejs.org/","npmPkgName":"three"},"PhiloGL":{"url":"http://www.senchalabs.org/philogl/","npmPkgName":"philogl"},"CamanJS":{"url":"http://camanjs.com/","npmPkgName":"caman"},"yepnope":{"url":"http://yepnopejs.com/"},"LABjs":{"url":"http://labjs.com/"},"Head JS":{"url":"http://headjs.com/","npmPkgName":"headjs"},"ControlJS":{"url":"http://stevesouders.com/controljs/"},"RequireJS":{"url":"http://requirejs.org/","npmPkgName":"requirejs"},"RightJS":{"url":"http://rightjs.org/"},"jQuery Tools":{"url":"http://jquerytools.github.io/"},"Pusher":{"url":"http://pusher.com/docs/pusher_js/","npmPkgName":"pusher-js"},"Paper.js":{"url":"http://paperjs.org/","npmPkgName":"paper"},"Swiffy":{"url":"http://www.google.com/doubleclick/studio/swiffy/"},"Move":{"url":"https://github.com/rsms/move","npmPkgName":"move"},"AmplifyJS":{"url":"http://amplifyjs.com/","npmPkgName":"amplifyjs"},"Popcorn.js":{"url":"http://popcornjs.org/"},"D3":{"url":"http://d3js.org","npmPkgName":"d3"},"Handlebars":{"url":"http://handlebarsjs.com/","npmPkgName":"handlebars"},"Knockout":{"url":"http://knockoutjs.com/","npmPkgName":"knockout"},"Spine":{"url":"http://spinejs.com/"},"jQuery Mobile":{"url":"http://jquerymobile.com/","npmPkgName":"jquery-mobile"},"WebFont Loader":{"url":"https://github.com/typekit/webfontloader","npmPkgName":"webfontloader"},"Angular":{"url":"https://angular.io/","npmPkgName":"@angular/core"},"AngularJS":{"url":"http://angularjs.org","npmPkgName":"angular"},"Ember.js":{"url":"http://emberjs.com/","npmPkgName":"ember-source"},"Hammer.js":{"url":"http://eightmedia.github.io/hammer.js/","npmPkgName":"hammerjs"},"Visibility.js":{"url":"https://github.com/ai/visibilityjs","npmPkgName":"visibilityjs"},"Velocity.js":{"url":"http://velocityjs.org/","npmPkgName":"velocity-animate"},"IfVisible.js":{"url":"http://serkanyersen.github.io/ifvisible.js/","npmPkgName":"ifvisible.js"},"Pixi.js":{"url":"https://github.com/GoodBoyDigital/pixi.js","npmPkgName":"pixi.js"},"DC.js":{"url":"http://dc-js.github.io/dc.js/","npmPkgName":"dc"},"Greensock JS":{"url":"https://github.com/greensock/GreenSock-JS","npmPkgName":"gsap"},"FastClick":{"url":"https://github.com/ftlabs/fastclick","npmPkgName":"fastclick"},"Isotope":{"url":"http://isotope.metafizzy.co/","npmPkgName":"isotope-layout"},"Marionette":{"url":"http://marionettejs.com/","npmPkgName":"backbone.marionette"},"Can":{"url":"http://canjs.com/","npmPkgName":"can"},"Vue":{"url":"http://vuejs.org/","npmPkgName":"vue"},"Two":{"url":"https://jonobr1.github.io/two.js","npmPkgName":"two.js"},"Brewser":{"url":"http://handcraftedldn.github.io/brewser/","npmPkgName":"brewser"},"Material Design Lite":{"url":"http://www.getmdl.io/","npmPkgName":"material-design-lite"},"Kendo UI":{"url":"https://github.com/telerik/kendo-ui-core","npmPkgName":"kendo-ui-core"},"Matter.js":{"url":"http://brm.io/matter-js/","npmPkgName":"matter-js"},"Riot":{"url":"http://riotjs.com/","npmPkgName":"riot"},"Sea.js":{"url":"http://seajs.org/","npmPkgName":"seajs"},"Moment.js":{"url":"http://momentjs.com/","npmPkgName":"moment"},"Moment Timezone":{"url":"http://momentjs.com/timezone/","npmPkgName":"moment-timezone"},"ScrollMagic":{"url":"http://scrollmagic.io/","npmPkgName":"scrollmagic"},"SWFObject":{"url":"https://github.com/swfobject/swfobject"},"FlexSlider":{"url":"https://woocommerce.com/flexslider/","npmPkgName":"flexslider"},"SPF":{"url":"https://youtube.github.io/spfjs/","npmPkgName":"spf"},"Numeral.js":{"url":"http://numeraljs.com/","npmPkgName":"numeraljs"},"boomerang.js":{"url":"https://soasta.github.io/boomerang/doc/","npmPkgName":"boomerangjs"}};
// From https://raw.githubusercontent.com/johnmichel/Library-Detector-for-Chrome/master/library/libraries.js
var UNKNOWN_VERSION=null;
var lighthouseJSLibs={GWT:{icon:"gwt",url:"http://www.gwtproject.org/",test:function(win){var doc=win.document,hasHistFrame=doc.getElementById("__gwt_historyFrame"),hasGwtUid=doc.gwt_uid,hasBodyListener=doc.body.__listener,hasBodyEventBits=doc.body.__eventBits,hasModules=win.__gwt_activeModules,hasJsonP=win.__gwt_jsonp__,hasRootWinApp=win.__gwt_scriptsLoaded||win.__gwt_stylesLoaded||win.__gwt_activeModules;if(hasHistFrame||hasGwtUid||hasBodyListener||hasBodyEventBits||hasModules||hasJsonP||hasRootWinApp){var frames=doc.getElementsByTagName("iframe"),gwtVersion=UNKNOWN_VERSION;for(var n=0;n<frames.length;n++){try{var hasNegativeTabIndex=frames[n].tabIndex<0;if(hasNegativeTabIndex&&frames[n].contentWindow&&frames[n].contentWindow.$gwt_version){gwtVersion=frames[n].contentWindow.$gwt_version;break}}catch(e){}}if(gwtVersion=="0.0.999"){gwtVersion="Google Internal"}return{version:gwtVersion}}return false}},Ink:{icon:"ink",url:"http://ink.sapo.pt/",test:function(win){if(win.Ink&&win.Ink.createModule){return{version:UNKNOWN_VERSION}}return false}},Vaadin:{icon:"vaadin",url:"http://vaadin.com/home",test:function(win){if(win.vaadin&&win.vaadin.registerWidgetset){return{version:UNKNOWN_VERSION}}return false}},Bootstrap:{icon:"bootstrap",url:"http://getbootstrap.com/",test:function(win){var jQueryAvailable=win.$&&win.$.fn,RE_PREFIX_V2="\\$this\\.data\\((?:'|\")",RE_PREFIX_V3="\\$this\\.data\\((?:'|\")(?:bs\\.){1}",bootstrapComponents=["affix","alert","button","carousel","collapse","dropdown","modal","popover","scrollspy","tab","tooltip"];if(jQueryAvailable){var bootstrapVersion;bootstrapComponents.some(function(component){if(win.$.fn[component]){if(win.$.fn[component].Constructor&&win.$.fn[component].Constructor.VERSION){bootstrapVersion=win.$.fn[component].Constructor.VERSION;return true}else if(new RegExp(RE_PREFIX_V3+component).test(win.$.fn[component].toString())){bootstrapVersion=">= 3.0.0 & <= 3.1.1";return true}else if(new RegExp(RE_PREFIX_V2+component).test(win.$.fn[component].toString())){bootstrapVersion=">= 2.0.0 & <= 2.3.2";return true}}return false});if(bootstrapVersion){return{version:bootstrapVersion}}}return false}},Zurb:{icon:"zurb",url:"http://foundation.zurb.com/",test:function(win){if(win.Foundation){return{version:win.Foundation.version||UNKNOWN_VERSION}}return false}},Polymer:{icon:"polymer",url:"http://www.polymer-project.org/",test:function(win){if(win.Polymer){return{version:win.Polymer.version||UNKNOWN_VERSION}}return false}},Highcharts:{icon:"highcharts",url:"http://www.highcharts.com",test:function(win){if(win.Highcharts){return{version:win.Highcharts.version||UNKNOWN_VERSION}}return false}},InfoVis:{icon:"jit",url:"http://philogb.github.com/jit/",test:function(win){if(win.$jit){return{version:win.$jit.version||UNKNOWN_VERSION}}return false}},FlotCharts:{icon:"icon_48",url:"http://www.flotcharts.org/",test:function(win){if(win.$&&win.$.plot){return{version:win.$.plot.version||UNKNOWN_VERSION}}return false}},Blackbird:{icon:"blackbird",url:"http://www.gscottolson.com/blackbirdjs/",test:function(win){if(win.log&&win.log.warn){return{version:UNKNOWN_VERSION}}return false}},CreateJS:{icon:"createjs",url:"http://createjs.com/#!/CreateJS",test:function(win){if(win.Stage||win.Shape||win.Container){return{version:UNKNOWN_VERSION}}return false}},"Google Maps":{icon:"gmaps",url:"https://developers.google.com/maps/",test:function(win){if(win.google&&win.google.maps){return{version:win.google.maps.version||UNKNOWN_VERSION}}return false}},jQuery:{icon:"jquery",url:"http://jquery.com",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn){return{version:jq.fn.jquery||UNKNOWN_VERSION}}return false}},"jQuery UI":{icon:"jquery_ui",url:"http://jqueryui.com",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.ui){var plugins="accordion,datepicker,dialog,draggable,droppable,progressbar,resizable,selectable,slider,menu,grid,tabs".split(","),concat=[];for(var i=0;i<plugins.length;i++){if(jq.ui[plugins[i]])concat.push(plugins[i].substr(0,1).toUpperCase()+plugins[i].substr(1))}return{version:jq.ui.version||UNKNOWN_VERSION,details:concat.length?"Plugins used: "+concat.join(","):""}}return false}},Dojo:{icon:"dojo",url:"http://dojotoolkit.org",test:function(win){if(win.dojo){var version=win.dojo.version?win.dojo.version.toString():UNKNOWN_VERSION;return{version:version,details:"Details: "+(win.dijit?"Uses Dijit":"none")}}return false}},Prototype:{icon:"prototype",url:"http://prototypejs.org",test:function(win){if(win.Prototype){return{version:win.Prototype.Version||UNKNOWN_VERSION}}return false}},Scriptaculous:{icon:"scriptaculous",url:"http://script.aculo.us",test:function(win){if(win.Scriptaculous){return{version:win.Scriptaculous.Version||UNKNOWN_VERSION}}return false}},MooTools:{icon:"mootools",url:"http://mootools.net",test:function(win){if(win.MooTools){return{version:win.MooTools.version||UNKNOWN_VERSION}}return false}},Spry:{icon:"spry",url:"http://labs.adobe.com/technologies/spry",test:function(win){if(win.Spry&&win.Spry.Data){return{version:UNKNOWN_VERSION}}return false}},"YUI 2":{icon:"yui",url:"http://developer.yahoo.com/yui/2/",test:function(win){if(win.YAHOO){return{version:win.YAHOO.VERSION||UNKNOWN_VERSION}}return false}},"YUI 3":{icon:"yui3",url:"http://yuilibrary.com/",test:function(win){if(win.YUI&&win.YUI.Env){return{version:win.YUI.version||UNKNOWN_VERSION}}return false}},Qooxdoo:{icon:"qooxdoo",url:"http://qooxdoo.org",test:function(win){if(win.qx&&win.qx.Bootstrap){return{version:UNKNOWN_VERSION}}return false}},"Ext JS":{icon:"extjs",url:"http://www.sencha.com/products/extjs",test:function(win){if(win.Ext&&win.Ext.versions){return{version:win.Ext.versions.core.version}}else if(win.Ext){return{version:win.Ext.version||UNKNOWN_VERSION}}return false}},base2:{icon:"base2",url:"http://code.google.com/p/base2",test:function(win){if(win.base2){return{version:win.base2.version||UNKNOWN_VERSION}}return false}},"Closure Library":{icon:"closure",url:"https://developers.google.com/closure/library",test:function(win){if(win.goog&&win.goog.provide){return{version:UNKNOWN_VERSION}}return false}},"Rapha&euml;l":{icon:"raphael",url:"http://dmitrybaranovskiy.github.io/raphael",test:function(win){if(win.Raphael&&win.Raphael.circle){return{version:win.Raphael.version||UNKNOWN_VERSION}}return false}},React:{icon:"react",url:"http://facebook.github.io/react/",test:function(win){if(win.React&&win.React.createClass){return{version:win.React.version||UNKNOWN_VERSION}}if(win.__REACT_DEVTOOLS_GLOBAL_HOOK__){return{version:UNKNOWN_VERSION}}return false}},Modernizr:{icon:"modernizr",url:"http://www.modernizr.com",test:function(win){if(win.Modernizr&&win.Modernizr.addTest){return{version:win.Modernizr._version||UNKNOWN_VERSION}}return false}},"Processing.js":{icon:"processingjs",url:"http://processingjs.org",test:function(win){if(win.Processing&&win.Processing.box){return{version:Processing.version||UNKNOWN_VERSION}}return false}},Backbone:{icon:"backbone",url:"http://backbonejs.org/",test:function(win){if(win.Backbone&&win.Backbone.Model.extend){return{version:win.Backbone.VERSION||UNKNOWN_VERSION}}return false}},Leaflet:{icon:"leaflet",url:"http://leafletjs.com",test:function(win){if(win.L&&win.L.GeoJSON&&(win.L.marker||win.L.Marker)){return{version:win.L.version||win.L.VERSION||UNKNOWN_VERSION}}return false}},Mapbox:{icon:"mapbox",url:"http://mapbox.com",test:function(win){if(win.L&&win.L.mapbox&&win.L.mapbox.geocoder){return{version:win.L.mapbox.VERSION||UNKNOWN_VERSION}}return false}},"Lo-Dash":{icon:"lodash",url:"http://lodash.com/",test:function(win){var _=typeof(_=win._)=="function"&&_,chain=typeof(chain=_&&_.chain)=="function"&&chain,wrapper=(chain||_||function(){return{}})(1);if(_&&wrapper.__wrapped__){return{version:_.VERSION||UNKNOWN_VERSION}}return false}},Underscore:{icon:"underscore",url:"http://underscorejs.org/",test:function(win){if(win._&&typeof win._.tap==="function"&&!d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests["Lo-Dash"].test(win)){return{version:win._.VERSION||UNKNOWN_VERSION}}return false}},Sammy:{icon:"sammy",url:"http://sammyjs.org",test:function(win){if(win.Sammy&&win.Sammy.Application.curry){return{version:win.Sammy.VERSION||UNKNOWN_VERSION}}return false}},Rico:{icon:"rico",url:"http://openrico.sourceforge.net/examples/index.html",test:function(win){if(win.Rico){return{version:win.Rico.Version||UNKNOWN_VERSION}}return false}},MochiKit:{icon:"mochikit",url:"https://mochi.github.io/mochikit/",test:function(win){if(win.MochiKit&&win.MochiKit.Base.module){return{version:MochiKit.VERSION||UNKNOWN_VERSION}}return false}},"gRapha&euml;l":{icon:"graphael",url:"http://g.raphaeljs.com",test:function(win){if(win.Raphael&&win.Raphael.fn.g){return{version:UNKNOWN_VERSION}}return false}},Glow:{icon:"glow",url:"http://www.bbc.co.uk/glow",test:function(win){if(win.gloader){return{version:UNKNOWN_VERSION}}else if(win.glow&&win.glow.dom){return{version:win.glow.VERSION||UNKNOWN_VERSION}}else if(win.Glow){return{version:win.Glow.version||UNKNOWN_VERSION}}return false}},"Socket.IO":{icon:"socketio",url:"http://socket.io",test:function(win){if(win.io&&(win.io.sockets||win.io.Socket)){return{version:win.io.version||UNKNOWN_VERSION}}return false}},Mustache:{icon:"mustache",url:"http://mustache.github.com",test:function(win){if(win.Mustache&&win.Mustache.to_html){return{version:win.Mustache.version||UNKNOWN_VERSION}}return false}},"Fabric.js":{icon:"icon_48",url:"http://fabricjs.com/",test:function(win){if(win.fabric&&win.fabric.util){return{version:win.fabric.version||UNKNOWN_VERSION}}return false}},FuseJS:{icon:"fusejs",url:"http://kiro.me/projects/fuse.html",test:function(win){if(win.fuse){return{version:win.fuse.version||UNKNOWN_VERSION}}return false}},"Tween.js":{icon:"icon_48",url:"https://github.com/sole/tween.js",test:function(win){if(win.TWEEN&&win.TWEEN.Easing){return{version:UNKNOWN_VERSION}}return false}},SproutCore:{icon:"sproutcore",url:"http://www.sproutcore.com",test:function(win){if(win.SC&&win.SC.Application){return{version:UNKNOWN_VERSION}}return false}},"Zepto.js":{icon:"zepto",url:"http://zeptojs.com",test:function(win){if(win.Zepto&&win.Zepto.fn){return{version:UNKNOWN_VERSION}}return false}},"three.js":{icon:"icon_48",url:"http://threejs.org/",test:function(win){if(win.THREE&&win.THREE.REVISION){return{version:"r"+win.THREE.REVISION}}else if(win.THREE){return{version:UNKNOWN_VERSION}}return false}},PhiloGL:{icon:"philogl",url:"http://www.senchalabs.org/philogl/",test:function(win){if(win.PhiloGL&&win.PhiloGL.Camera){return{version:win.PhiloGL.version||UNKNOWN_VERSION}}return false}},CamanJS:{icon:"camanjs",url:"http://camanjs.com/",test:function(win){if(win.Caman&&win.Caman.version){return{version:win.Caman.version.release}}else if(win.Caman){return{version:UNKNOWN_VERSION}}return false}},yepnope:{icon:"yepnope",url:"http://yepnopejs.com/",test:function(win){if(win.yepnope){return{version:UNKNOWN_VERSION}}return false}},LABjs:{icon:"icon_48",url:"http://labjs.com/",test:function(win){if(win.$LAB){return{version:UNKNOWN_VERSION}}return false}},"Head JS":{icon:"headjs",url:"http://headjs.com/",test:function(win){if(win.head&&win.head.js){return{version:UNKNOWN_VERSION}}return false}},ControlJS:{icon:"icon_48",url:"http://stevesouders.com/controljs/",test:function(win){if(win.CJS&&win.CJS.start){return{version:UNKNOWN_VERSION}}return false}},RequireJS:{icon:"requirejs",url:"http://requirejs.org/",test:function(win){var req=win.require||win.requirejs;if(req&&(req.load||req.s&&req.s.contexts&&req.s.contexts._&&(req.s.contexts._.loaded||req.s.contexts._.load))){return{version:req.version||UNKNOWN_VERSION}}return false}},RightJS:{icon:"rightjs",url:"http://rightjs.org/",test:function(win){if(win.RightJS&&win.RightJS.isNode){return{version:win.RightJS.version||UNKNOWN_VERSION}}return false}},"jQuery Tools":{icon:"jquerytools",url:"http://jquerytools.github.io/",test:function(win){var jq=win.jQuery||win.$;if(jq&&jq.tools){return{version:jq.tools.version||UNKNOWN_VERSION}}return false}},Pusher:{icon:"pusher",url:"http://pusher.com/docs/pusher_js/",test:function(win){if(win.Pusher&&win.Pusher.Channel){return{version:win.Pusher.VERSION||UNKNOWN_VERSION}}return false}},"Paper.js":{icon:"paperjs",url:"http://paperjs.org/",test:function(win){if(win.paper&&win.paper.Point){return{version:win.paper.version||UNKNOWN_VERSION}}return false}},Swiffy:{icon:"icon_48",url:"http://www.google.com/doubleclick/studio/swiffy/",test:function(win){if(win.swiffy){return{version:UNKNOWN_VERSION}}return false}},Move:{icon:"move",url:"https://github.com/rsms/move",test:function(win){if(win.move&&win.move.compile){return{version:win.move.version()||UNKNOWN_VERSION}}return false}},AmplifyJS:{icon:"amplifyjs",url:"http://amplifyjs.com/",test:function(win){if(win.amplify&&win.amplify.publish){return{version:UNKNOWN_VERSION}}return false}},"Popcorn.js":{icon:"popcornjs",url:"http://popcornjs.org/",test:function(win){if(win.Popcorn&&win.Popcorn.Events){return{version:win.Popcorn.version||UNKNOWN_VERSION}}return false}},D3:{icon:"d3",url:"http://d3js.org",test:function(win){if(win.d3&&win.d3.select){return{version:win.d3.version||UNKNOWN_VERSION}}return false}},Handlebars:{icon:"handlebars",url:"http://handlebarsjs.com/",test:function(win){if(win.Handlebars&&win.Handlebars.compile){return{version:win.Handlebars.VERSION||UNKNOWN_VERSION}}return false}},Knockout:{icon:"knockout",url:"http://knockoutjs.com/",test:function(win){if(win.ko&&win.ko.applyBindings){return{version:win.ko.version||UNKNOWN_VERSION}}return false}},Spine:{icon:"icon_48",url:"http://spinejs.com/",test:function(win){if(win.Spine&&win.Spine.Controller){return{version:win.Spine.version||UNKNOWN_VERSION}}return false}},"jQuery Mobile":{icon:"jquery_mobile",url:"http://jquerymobile.com/",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.mobile){return{version:jq.mobile.version||UNKNOWN_VERSION}}return false}},"WebFont Loader":{icon:"icon_48",url:"https://github.com/typekit/webfontloader",test:function(win){if(win.WebFont&&win.WebFont.load){return{version:UNKNOWN_VERSION}}return false}},Angular:{icon:"angular",url:"https://angular.io/",test:function(win){var ng=win.document.querySelector("[ng-version]");if(ng){return{version:ng.getAttribute("ng-version")||UNKNOWN_VERSION}}return false}},AngularJS:{icon:"angularjs",url:"http://angularjs.org",test:function(win){var ng=win.angular;if(ng&&ng.version&&ng.version.full){return{version:ng.version.full}}else if(ng){return{version:UNKNOWN_VERSION}}return false}},"Ember.js":{icon:"emberjs",url:"http://emberjs.com/",test:function(win){var ember=win.Ember||win.Em;if(ember&&ember.propertyDidChange){return{version:ember.VERSION||UNKNOWN_VERSION}}return false}},"Hammer.js":{icon:"hammerjs",url:"http://eightmedia.github.io/hammer.js/",test:function(win){var hammer=win.Hammer;if(hammer&&hammer.Pinch){return{version:hammer.VERSION||"&lt; 1.0.10"}}return false}},"Visibility.js":{icon:"icon_48",url:"https://github.com/ai/visibilityjs",test:function(win){var visibility=win.Visibility;if(visibility&&visibility.every){return{version:UNKNOWN_VERSION}}return false}},"Velocity.js":{icon:"icon_48",url:"http://velocityjs.org/",test:function(win){var jq=win.jQuery||win.$,velocity=jq?jq.Velocity:win.Velocity;if(velocity&&velocity.RegisterEffect&&velocity.version){return{version:velocity.version.major+"."+velocity.version.minor+"."+velocity.version.patch}}else if(velocity&&velocity.RegisterEffect){return{version:UNKNOWN_VERSION}}return false}},"IfVisible.js":{icon:"icon_48",url:"http://serkanyersen.github.io/ifvisible.js/",test:function(win){var iv=win.ifvisible;if(iv&&iv.__ceGUID==="ifvisible.object.event.identifier"){return{version:UNKNOWN_VERSION}}return false}},"Pixi.js":{icon:"pixi",url:"https://github.com/GoodBoyDigital/pixi.js",test:function(win){var px=win.PIXI;if(px&&px.WebGLRenderer&&px.VERSION){return{version:px.VERSION.replace("v","")||UNKNOWN_VERSION}}return false}},"DC.js":{icon:"icon_48",url:"http://dc-js.github.io/dc.js/",test:function(win){var dc=win.dc;if(dc&&dc.registerChart){return{version:dc.version||UNKNOWN_VERSION}}return false}},"Greensock JS":{icon:"greensock",url:"https://github.com/greensock/GreenSock-JS",test:function(win){var gs=win.TweenMax||win.TweenLite;if(gs){return{version:gs.version||UNKNOWN_VERSION}}return false}},FastClick:{icon:"fastclick",url:"https://github.com/ftlabs/fastclick",test:function(win){if(win.FastClick&&win.FastClick.notNeeded){return{version:UNKNOWN_VERSION}}return false}},Isotope:{icon:"isotope",url:"http://isotope.metafizzy.co/",test:function(win){var iso=win.Isotope||win.$!=null&&win.$.Isotope;if(iso){return{version:UNKNOWN_VERSION}}return false}},Marionette:{icon:"marionette",url:"http://marionettejs.com/",test:function(win){if(win.Marionette&&win.Marionette.Application){return{version:win.Marionette.VERSION||UNKNOWN_VERSION}}return false}},Can:{icon:"icon_48",url:"http://canjs.com/",test:function(win){if(win.can&&win.can.Construct){return{version:win.can.VERSION||UNKNOWN_VERSION}}return false}},Vue:{icon:"vue",url:"http://vuejs.org/",test:function(win){if(win.Vue&&win.Vue.nextTick){return{version:win.Vue.version||UNKNOWN_VERSION}}return false}},Two:{icon:"two",url:"https://jonobr1.github.io/two.js",test:function(win){if(win.Two&&win.Two.Utils){return{version:win.Two.Version||UNKNOWN_VERSION}}return false}},Brewser:{icon:"brewser",url:"http://handcraftedldn.github.io/brewser/",test:function(win){if(win.BREWSER&&win.BREWSER.ua){return{version:BREWSER.VERSION||UNKNOWN_VERSION}}return false}},"Material Design Lite":{icon:"mdl",url:"http://www.getmdl.io/",test:function(win){if(win.componentHandler&&win.componentHandler.upgradeElement){return{version:UNKNOWN_VERSION}}return false}},"Kendo UI":{icon:"kendoui",url:"https://github.com/telerik/kendo-ui-core",test:function(win){if(win.kendo&&win.kendo.View&&win.kendo.View.extend){return{version:win.kendo.version||UNKNOWN_VERSION}}return false}},"Matter.js":{icon:"matter-js",url:"http://brm.io/matter-js/",test:function(win){if(win.Matter&&win.Matter.Engine){return{version:UNKNOWN_VERSION}}return false}},Riot:{icon:"riot",url:"http://riotjs.com/",test:function(win){if(win.riot&&win.riot.mixin){return{version:win.riot.version||UNKNOWN_VERSION}}return false}},"Sea.js":{icon:"icon_48",url:"http://seajs.org/",test:function(win){if(win.seajs&&win.seajs.use){return{version:win.seajs.version||UNKNOWN_VERSION}}return false}},"Moment.js":{icon:"momentjs",url:"http://momentjs.com/",test:function(win){if(win.moment&&(win.moment.isMoment||win.moment.lang)){return{version:win.moment.version||UNKNOWN_VERSION}}return false}},"Moment Timezone":{icon:"momentjs",url:"http://momentjs.com/timezone/",test:function(win){if(win.moment&&win.moment.tz){return{version:win.moment.tz.version||UNKNOWN_VERSION}}return false}},ScrollMagic:{icon:"scrollmagic",url:"http://scrollmagic.io/",test:function(win){if(win.ScrollMagic&&win.ScrollMagic.Controller){return{version:ScrollMagic.version||UNKNOWN_VERSION}}return false}},SWFObject:{icon:"icon_48",url:"https://github.com/swfobject/swfobject",test:function(win){if(win.swfobject&&win.swfobject.embedSWF){return{version:win.swfobject.version||UNKNOWN_VERSION}}else if(win.deconcept&&win.deconcept.SWFObject){return{version:UNKNOWN_VERSION}}return false}},FlexSlider:{icon:"icon_48",url:"https://woocommerce.com/flexslider/",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.flexslider){return{version:UNKNOWN_VERSION}}return false}},SPF:{icon:"icon_48",url:"https://youtube.github.io/spfjs/",test:function(win){if(win.spf&&win.spf.init){return{version:UNKNOWN_VERSION}}return false}},"Numeral.js":{icon:"icon_48",url:"http://numeraljs.com/",test:function(win){if(win.numeral&&win.isNumeral){return{version:win.numeral.version||UNKNOWN_VERSION}}return false}},"boomerang.js":{icon:"icon_48",url:"https://soasta.github.io/boomerang/doc/",test:function(win){if(win.BOOMR&&win.BOOMR.utils&&win.BOOMR.init){return{version:win.BOOMR.version||UNKNOWN_VERSION}}return false}}};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

want to make these separate files which we can pass into the detectLibraries function as arguments with JSON.stringify or something? the accessibility audit does something similar with axe to try to keep the gatherer logic a bit separate

Copy link
Contributor Author

@tkadlec tkadlec May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely. In the case of both, they're coming from GH/Gist repos so we'll need a way to pull them in semi-regularly to make sure the latest versions are included. Would something akin to HTTPArchive/legacy.httparchive.org@5a624cb#diff-4df11ed88be41bcc1851345666d6f7b1 be the best option?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take a look at how we do the accessibility gatherer. we readFileSync the axe.min.js from the axe-core node module.

this way, versioning is pretty straightfoward as its just a node module dep bump.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to do this, but Library Detector isn't an npm module at the moment. :(

Maybe we can sweet talk @johnmichel into publishing it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm. filed johnmichel/Library-Detector-for-Chrome#98 to see if https://github.com/johnmichel/Library-Detector-for-Chrome/blob/master/library/libraries.js can be shipped on NPM

i can see a lot of activity on that file, so i'd prefer to have a nice versioning story for this first.

libraries[npmMapper[i].npmPkgName] = {"version": result.version};
}
} catch(e) {
console.log('Library Detector test for ' + i + ' failed:', e);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we wont' really be able to see these log statements easily, how about pushing these messages onto an array that we return along with libraries?

.then(returnedValue => {
return new Promise((resolve, reject) => {
// need to mimic package.json for now
const jsonBody = '{"name": "lighthouse", "version": "1.0",' +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we construct the entire body as an object and JSON.stringify the whole thing instead of just dependencies?

request.post({
headers: {
'content-type': 'application/json',
'Authorization': 'token 815130d4-940b-4252-b301-5ce28d734bf7'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a rate limit on this token/who manages it? i don't know much about snyk 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a special one I setup just for Lighthouse, so no—no limit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the token need to be kept secret? Can anyone just copy it can get unlimited snyk API calls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assumption was that given the nature of Lighthouse (where contributors will need to be able to clone and develop locally), a secret token wouldn't be very practical.

We can monitor this particular token for any non-Lighthouse usage on our end. So no...it won't be very useful to anyone else. :)

Copy link
Contributor

@ebidel ebidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT think about contributing https://gist.github.com/tkadlec/83146d8505d7748e8944bc333c166ad3 upstream? I worried about maintaining new file like this without the help of the security community.

return {
category: 'Security',
name: 'no-vulnerable-libraries',
description: 'Avoids using any front-end JavaScript libraries'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "using any"

description: 'Avoids using any front-end JavaScript libraries'
+ ' with known security vulnerabilities',
helpText: 'Sites should take care to ensure that they are not using any' +
' front-end JavaScript libraries that contain known security vulnerabilities.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repeats the description. Is there more we can say? Also throw in a [Learn more]() link to somewhere relevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the link, it looks like most (all?) other audits point to a page on Google Developers. Does it make sense to put something similar to https://developers.google.com/web/tools/lighthouse/audits/contrast-ratio together for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. @kaycebasques can work on that once we have the audit :)

Copy link
Collaborator

@wardpeet wardpeet May 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it has to be a developers.google.com blog post. Maybe it could be a snyk page that has some information about this? As long as it's explaining why we do it.

FYI: i'm not against adding it to the audit references :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typical pipeline is to link to some external doc while we put together an official doc on developers.google.com. The goal is to just provide some sort of further guidance for peeps that fail the test, so they're not like "wtf I'm failing this test and I have no idea what it means or how to fix it"

static audit(artifacts) {
const vulns = artifacts.JSVulnerableLibraries;

// Filter requests that are on the same host as the page and not over h2.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment looks out of date...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Embarassing! :) Fixed.

const vulns = artifacts.JSVulnerableLibraries;

// Filter requests that are on the same host as the page and not over h2.
const finalVulns = vulns.map(record => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: just return the obj like so:

const finalVulns = vulns.map(record => ({
  severity: record.severity,
  library: record.name + '@' + record.version,
  url: 'https://snyk.io/vuln/' + record.id
}));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTG


return {
rawValue: vulns.length === 0,
displayValue: displayValue,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

rawValue: vulns.length === 0,
displayVrawValue,
extendedInfo: {...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTG

return {
rawValue: vulns.length === 0,
displayValue: displayValue,
extendedInfo: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extendedInfo is legacy in LH 2.0. What do you think about just returning the new detail object. Our JSON results are getting out of control :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wouldn't say it's "legacy", but its there only for folks consuming more details in the LHR, usually via the lighthouse module. not there for presentational purposes.

I think this sorta return would make sense:

extendedInfo: {
  value: {
    vulnerabilities: finalVulns
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, I think. :)

So the way I was using it, apparently it was just unnecessary as I was also passing details. @rviscomi suggested including a full list of detected libs here as well, so I'm thinking:

extendedInfo: {
  value: {
    js_libs: libraries,
    vulnerabilities: finalVulns
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All set. See 26af245

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulirish anything that's useful is also being surfaced in details.items. If module consumers are pulling lower level details themselves, they're probably having a heck of time figuring out which of these to use/trust:

screen shot 2017-05-26 at 8 41 23 pm

It's time to nip bloat in the bud. #2276

@tkadlec
Copy link
Contributor Author

tkadlec commented May 26, 2017

@ebidel More than happy to put that where ever it makes sense. LH? Library Detector?

@ebidel
Copy link
Contributor

ebidel commented May 26, 2017

Library Detector?

Yea maybe? I'd imagine it may be useful to folks outside of Lighthouse.

@tkadlec
Copy link
Contributor Author

tkadlec commented May 26, 2017

Good call. Submitted a PR there. johnmichel/Library-Detector-for-Chrome#97

@brendankenny
Copy link
Member

To properly use the code, if at all possible we should pull in the library as a node module, similar to how axe is done.

If not, it'll need to go into third_party/ along with its LICENSE file.

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice. thanks for working on this. pretty cool to read through. :)

return {
rawValue: vulns.length === 0,
displayValue: displayValue,
extendedInfo: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wouldn't say it's "legacy", but its there only for folks consuming more details in the LHR, usually via the lighthouse module. not there for presentational purposes.

I think this sorta return would make sense:

extendedInfo: {
  value: {
    vulnerabilities: finalVulns
  }
}

const npmMapper = {"GWT":{"url":"http://www.gwtproject.org/"},"Ink":{"url":"http://ink.sapo.pt/"},"Vaadin":{"url":"http://vaadin.com/home"},"Bootstrap":{"url":"http://getbootstrap.com/","npmPkgName":"bootstrap"},"Zurb":{"url":"http://foundation.zurb.com/","npmPkgName":"foundation-sites"},"Polymer":{"url":"http://www.polymer-project.org/","npmPkgName":"@polymer/polymer"},"Highcharts":{"url":"http://www.highcharts.com","npmPkgName":"highcharts"},"InfoVis":{"url":"http://philogb.github.com/jit/"},"FlotCharts":{"url":"http://www.flotcharts.org/","npmPkgName":"flot"},"Blackbird":{"url":"http://www.gscottolson.com/blackbirdjs/"},"CreateJS":{"url":"http://createjs.com/#!/CreateJS","npmPkgName":"createjs"},"Google Maps":{"url":"https://developers.google.com/maps/"},"jQuery":{"url":"http://jquery.com","npmPkgName":"jquery"},"jQuery UI":{"url":"http://jqueryui.com","npmPkgName":"jquery-ui"},"Dojo":{"url":"http://dojotoolkit.org","npmPkgName":"dojo"},"Prototype":{"url":"http://prototypejs.org"},"Scriptaculous":{"url":"http://script.aculo.us"},"MooTools":{"url":"http://mootools.net"},"Spry":{"url":"http://labs.adobe.com/technologies/spry"},"YUI 2":{"url":"http://developer.yahoo.com/yui/2/"},"YUI 3":{"url":"http://yuilibrary.com/","npmPkgName":"yui"},"Qooxdoo":{"url":"http://qooxdoo.org","npmPkgName":"qooxdoo"},"Ext JS":{"url":"http://www.sencha.com/products/extjs"},"base2":{"url":"http://code.google.com/p/base2"},"Closure Library":{"url":"https://developers.google.com/closure/library","npmPkgName":"google-closure-library"},"Rapha&euml;l":{"url":"http://dmitrybaranovskiy.github.io/raphael"},"React":{"url":"http://facebook.github.io/react/","npmPkgName":"react"},"Modernizr":{"url":"http://www.modernizr.com","npmPkgName":"modernizr"},"Processing.js":{"url":"http://processingjs.org","npmPkgName":"processing-js"},"Backbone":{"url":"http://backbonejs.org/","npmPkgName":"backbone"},"Leaflet":{"url":"http://leafletjs.com","npmPkgName":"leaflet"},"Mapbox":{"url":"http://mapbox.com","npmPkgName":"mapbox-gl"},"Lo-Dash":{"url":"http://lodash.com/","npmPkgName":"lodash"},"Underscore":{"url":"http://underscorejs.org/","npmPkgName":"underscore"},"Sammy":{"url":"http://sammyjs.org"},"Rico":{"url":"http://openrico.sourceforge.net/examples/index.html"},"MochiKit":{"url":"https://mochi.github.io/mochikit/"},"gRapha&euml;l":{"url":"http://g.raphaeljs.com"},"Glow":{"url":"http://www.bbc.co.uk/glow"},"Socket.IO":{"url":"http://socket.io","npmPkgName":"socket.io"},"Mustache":{"url":"http://mustache.github.com","npmPkgName":"mustache"},"Fabric.js":{"url":"http://fabricjs.com/","npmPkgName":"fabric"},"FuseJS":{"url":"http://kiro.me/projects/fuse.html","npmPkgName":"fuse.js"},"Tween.js":{"url":"https://github.com/sole/tween.js","npmPkgName":"tween.js"},"SproutCore":{"url":"http://www.sproutcore.com"},"Zepto.js":{"url":"http://zeptojs.com","npmPkgName":"zepto"},"three.js":{"url":"http://threejs.org/","npmPkgName":"three"},"PhiloGL":{"url":"http://www.senchalabs.org/philogl/","npmPkgName":"philogl"},"CamanJS":{"url":"http://camanjs.com/","npmPkgName":"caman"},"yepnope":{"url":"http://yepnopejs.com/"},"LABjs":{"url":"http://labjs.com/"},"Head JS":{"url":"http://headjs.com/","npmPkgName":"headjs"},"ControlJS":{"url":"http://stevesouders.com/controljs/"},"RequireJS":{"url":"http://requirejs.org/","npmPkgName":"requirejs"},"RightJS":{"url":"http://rightjs.org/"},"jQuery Tools":{"url":"http://jquerytools.github.io/"},"Pusher":{"url":"http://pusher.com/docs/pusher_js/","npmPkgName":"pusher-js"},"Paper.js":{"url":"http://paperjs.org/","npmPkgName":"paper"},"Swiffy":{"url":"http://www.google.com/doubleclick/studio/swiffy/"},"Move":{"url":"https://github.com/rsms/move","npmPkgName":"move"},"AmplifyJS":{"url":"http://amplifyjs.com/","npmPkgName":"amplifyjs"},"Popcorn.js":{"url":"http://popcornjs.org/"},"D3":{"url":"http://d3js.org","npmPkgName":"d3"},"Handlebars":{"url":"http://handlebarsjs.com/","npmPkgName":"handlebars"},"Knockout":{"url":"http://knockoutjs.com/","npmPkgName":"knockout"},"Spine":{"url":"http://spinejs.com/"},"jQuery Mobile":{"url":"http://jquerymobile.com/","npmPkgName":"jquery-mobile"},"WebFont Loader":{"url":"https://github.com/typekit/webfontloader","npmPkgName":"webfontloader"},"Angular":{"url":"https://angular.io/","npmPkgName":"@angular/core"},"AngularJS":{"url":"http://angularjs.org","npmPkgName":"angular"},"Ember.js":{"url":"http://emberjs.com/","npmPkgName":"ember-source"},"Hammer.js":{"url":"http://eightmedia.github.io/hammer.js/","npmPkgName":"hammerjs"},"Visibility.js":{"url":"https://github.com/ai/visibilityjs","npmPkgName":"visibilityjs"},"Velocity.js":{"url":"http://velocityjs.org/","npmPkgName":"velocity-animate"},"IfVisible.js":{"url":"http://serkanyersen.github.io/ifvisible.js/","npmPkgName":"ifvisible.js"},"Pixi.js":{"url":"https://github.com/GoodBoyDigital/pixi.js","npmPkgName":"pixi.js"},"DC.js":{"url":"http://dc-js.github.io/dc.js/","npmPkgName":"dc"},"Greensock JS":{"url":"https://github.com/greensock/GreenSock-JS","npmPkgName":"gsap"},"FastClick":{"url":"https://github.com/ftlabs/fastclick","npmPkgName":"fastclick"},"Isotope":{"url":"http://isotope.metafizzy.co/","npmPkgName":"isotope-layout"},"Marionette":{"url":"http://marionettejs.com/","npmPkgName":"backbone.marionette"},"Can":{"url":"http://canjs.com/","npmPkgName":"can"},"Vue":{"url":"http://vuejs.org/","npmPkgName":"vue"},"Two":{"url":"https://jonobr1.github.io/two.js","npmPkgName":"two.js"},"Brewser":{"url":"http://handcraftedldn.github.io/brewser/","npmPkgName":"brewser"},"Material Design Lite":{"url":"http://www.getmdl.io/","npmPkgName":"material-design-lite"},"Kendo UI":{"url":"https://github.com/telerik/kendo-ui-core","npmPkgName":"kendo-ui-core"},"Matter.js":{"url":"http://brm.io/matter-js/","npmPkgName":"matter-js"},"Riot":{"url":"http://riotjs.com/","npmPkgName":"riot"},"Sea.js":{"url":"http://seajs.org/","npmPkgName":"seajs"},"Moment.js":{"url":"http://momentjs.com/","npmPkgName":"moment"},"Moment Timezone":{"url":"http://momentjs.com/timezone/","npmPkgName":"moment-timezone"},"ScrollMagic":{"url":"http://scrollmagic.io/","npmPkgName":"scrollmagic"},"SWFObject":{"url":"https://github.com/swfobject/swfobject"},"FlexSlider":{"url":"https://woocommerce.com/flexslider/","npmPkgName":"flexslider"},"SPF":{"url":"https://youtube.github.io/spfjs/","npmPkgName":"spf"},"Numeral.js":{"url":"http://numeraljs.com/","npmPkgName":"numeraljs"},"boomerang.js":{"url":"https://soasta.github.io/boomerang/doc/","npmPkgName":"boomerangjs"}};
// From https://raw.githubusercontent.com/johnmichel/Library-Detector-for-Chrome/master/library/libraries.js
var UNKNOWN_VERSION=null;
var lighthouseJSLibs={GWT:{icon:"gwt",url:"http://www.gwtproject.org/",test:function(win){var doc=win.document,hasHistFrame=doc.getElementById("__gwt_historyFrame"),hasGwtUid=doc.gwt_uid,hasBodyListener=doc.body.__listener,hasBodyEventBits=doc.body.__eventBits,hasModules=win.__gwt_activeModules,hasJsonP=win.__gwt_jsonp__,hasRootWinApp=win.__gwt_scriptsLoaded||win.__gwt_stylesLoaded||win.__gwt_activeModules;if(hasHistFrame||hasGwtUid||hasBodyListener||hasBodyEventBits||hasModules||hasJsonP||hasRootWinApp){var frames=doc.getElementsByTagName("iframe"),gwtVersion=UNKNOWN_VERSION;for(var n=0;n<frames.length;n++){try{var hasNegativeTabIndex=frames[n].tabIndex<0;if(hasNegativeTabIndex&&frames[n].contentWindow&&frames[n].contentWindow.$gwt_version){gwtVersion=frames[n].contentWindow.$gwt_version;break}}catch(e){}}if(gwtVersion=="0.0.999"){gwtVersion="Google Internal"}return{version:gwtVersion}}return false}},Ink:{icon:"ink",url:"http://ink.sapo.pt/",test:function(win){if(win.Ink&&win.Ink.createModule){return{version:UNKNOWN_VERSION}}return false}},Vaadin:{icon:"vaadin",url:"http://vaadin.com/home",test:function(win){if(win.vaadin&&win.vaadin.registerWidgetset){return{version:UNKNOWN_VERSION}}return false}},Bootstrap:{icon:"bootstrap",url:"http://getbootstrap.com/",test:function(win){var jQueryAvailable=win.$&&win.$.fn,RE_PREFIX_V2="\\$this\\.data\\((?:'|\")",RE_PREFIX_V3="\\$this\\.data\\((?:'|\")(?:bs\\.){1}",bootstrapComponents=["affix","alert","button","carousel","collapse","dropdown","modal","popover","scrollspy","tab","tooltip"];if(jQueryAvailable){var bootstrapVersion;bootstrapComponents.some(function(component){if(win.$.fn[component]){if(win.$.fn[component].Constructor&&win.$.fn[component].Constructor.VERSION){bootstrapVersion=win.$.fn[component].Constructor.VERSION;return true}else if(new RegExp(RE_PREFIX_V3+component).test(win.$.fn[component].toString())){bootstrapVersion=">= 3.0.0 & <= 3.1.1";return true}else if(new RegExp(RE_PREFIX_V2+component).test(win.$.fn[component].toString())){bootstrapVersion=">= 2.0.0 & <= 2.3.2";return true}}return false});if(bootstrapVersion){return{version:bootstrapVersion}}}return false}},Zurb:{icon:"zurb",url:"http://foundation.zurb.com/",test:function(win){if(win.Foundation){return{version:win.Foundation.version||UNKNOWN_VERSION}}return false}},Polymer:{icon:"polymer",url:"http://www.polymer-project.org/",test:function(win){if(win.Polymer){return{version:win.Polymer.version||UNKNOWN_VERSION}}return false}},Highcharts:{icon:"highcharts",url:"http://www.highcharts.com",test:function(win){if(win.Highcharts){return{version:win.Highcharts.version||UNKNOWN_VERSION}}return false}},InfoVis:{icon:"jit",url:"http://philogb.github.com/jit/",test:function(win){if(win.$jit){return{version:win.$jit.version||UNKNOWN_VERSION}}return false}},FlotCharts:{icon:"icon_48",url:"http://www.flotcharts.org/",test:function(win){if(win.$&&win.$.plot){return{version:win.$.plot.version||UNKNOWN_VERSION}}return false}},Blackbird:{icon:"blackbird",url:"http://www.gscottolson.com/blackbirdjs/",test:function(win){if(win.log&&win.log.warn){return{version:UNKNOWN_VERSION}}return false}},CreateJS:{icon:"createjs",url:"http://createjs.com/#!/CreateJS",test:function(win){if(win.Stage||win.Shape||win.Container){return{version:UNKNOWN_VERSION}}return false}},"Google Maps":{icon:"gmaps",url:"https://developers.google.com/maps/",test:function(win){if(win.google&&win.google.maps){return{version:win.google.maps.version||UNKNOWN_VERSION}}return false}},jQuery:{icon:"jquery",url:"http://jquery.com",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn){return{version:jq.fn.jquery||UNKNOWN_VERSION}}return false}},"jQuery UI":{icon:"jquery_ui",url:"http://jqueryui.com",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.ui){var plugins="accordion,datepicker,dialog,draggable,droppable,progressbar,resizable,selectable,slider,menu,grid,tabs".split(","),concat=[];for(var i=0;i<plugins.length;i++){if(jq.ui[plugins[i]])concat.push(plugins[i].substr(0,1).toUpperCase()+plugins[i].substr(1))}return{version:jq.ui.version||UNKNOWN_VERSION,details:concat.length?"Plugins used: "+concat.join(","):""}}return false}},Dojo:{icon:"dojo",url:"http://dojotoolkit.org",test:function(win){if(win.dojo){var version=win.dojo.version?win.dojo.version.toString():UNKNOWN_VERSION;return{version:version,details:"Details: "+(win.dijit?"Uses Dijit":"none")}}return false}},Prototype:{icon:"prototype",url:"http://prototypejs.org",test:function(win){if(win.Prototype){return{version:win.Prototype.Version||UNKNOWN_VERSION}}return false}},Scriptaculous:{icon:"scriptaculous",url:"http://script.aculo.us",test:function(win){if(win.Scriptaculous){return{version:win.Scriptaculous.Version||UNKNOWN_VERSION}}return false}},MooTools:{icon:"mootools",url:"http://mootools.net",test:function(win){if(win.MooTools){return{version:win.MooTools.version||UNKNOWN_VERSION}}return false}},Spry:{icon:"spry",url:"http://labs.adobe.com/technologies/spry",test:function(win){if(win.Spry&&win.Spry.Data){return{version:UNKNOWN_VERSION}}return false}},"YUI 2":{icon:"yui",url:"http://developer.yahoo.com/yui/2/",test:function(win){if(win.YAHOO){return{version:win.YAHOO.VERSION||UNKNOWN_VERSION}}return false}},"YUI 3":{icon:"yui3",url:"http://yuilibrary.com/",test:function(win){if(win.YUI&&win.YUI.Env){return{version:win.YUI.version||UNKNOWN_VERSION}}return false}},Qooxdoo:{icon:"qooxdoo",url:"http://qooxdoo.org",test:function(win){if(win.qx&&win.qx.Bootstrap){return{version:UNKNOWN_VERSION}}return false}},"Ext JS":{icon:"extjs",url:"http://www.sencha.com/products/extjs",test:function(win){if(win.Ext&&win.Ext.versions){return{version:win.Ext.versions.core.version}}else if(win.Ext){return{version:win.Ext.version||UNKNOWN_VERSION}}return false}},base2:{icon:"base2",url:"http://code.google.com/p/base2",test:function(win){if(win.base2){return{version:win.base2.version||UNKNOWN_VERSION}}return false}},"Closure Library":{icon:"closure",url:"https://developers.google.com/closure/library",test:function(win){if(win.goog&&win.goog.provide){return{version:UNKNOWN_VERSION}}return false}},"Rapha&euml;l":{icon:"raphael",url:"http://dmitrybaranovskiy.github.io/raphael",test:function(win){if(win.Raphael&&win.Raphael.circle){return{version:win.Raphael.version||UNKNOWN_VERSION}}return false}},React:{icon:"react",url:"http://facebook.github.io/react/",test:function(win){if(win.React&&win.React.createClass){return{version:win.React.version||UNKNOWN_VERSION}}if(win.__REACT_DEVTOOLS_GLOBAL_HOOK__){return{version:UNKNOWN_VERSION}}return false}},Modernizr:{icon:"modernizr",url:"http://www.modernizr.com",test:function(win){if(win.Modernizr&&win.Modernizr.addTest){return{version:win.Modernizr._version||UNKNOWN_VERSION}}return false}},"Processing.js":{icon:"processingjs",url:"http://processingjs.org",test:function(win){if(win.Processing&&win.Processing.box){return{version:Processing.version||UNKNOWN_VERSION}}return false}},Backbone:{icon:"backbone",url:"http://backbonejs.org/",test:function(win){if(win.Backbone&&win.Backbone.Model.extend){return{version:win.Backbone.VERSION||UNKNOWN_VERSION}}return false}},Leaflet:{icon:"leaflet",url:"http://leafletjs.com",test:function(win){if(win.L&&win.L.GeoJSON&&(win.L.marker||win.L.Marker)){return{version:win.L.version||win.L.VERSION||UNKNOWN_VERSION}}return false}},Mapbox:{icon:"mapbox",url:"http://mapbox.com",test:function(win){if(win.L&&win.L.mapbox&&win.L.mapbox.geocoder){return{version:win.L.mapbox.VERSION||UNKNOWN_VERSION}}return false}},"Lo-Dash":{icon:"lodash",url:"http://lodash.com/",test:function(win){var _=typeof(_=win._)=="function"&&_,chain=typeof(chain=_&&_.chain)=="function"&&chain,wrapper=(chain||_||function(){return{}})(1);if(_&&wrapper.__wrapped__){return{version:_.VERSION||UNKNOWN_VERSION}}return false}},Underscore:{icon:"underscore",url:"http://underscorejs.org/",test:function(win){if(win._&&typeof win._.tap==="function"&&!d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests["Lo-Dash"].test(win)){return{version:win._.VERSION||UNKNOWN_VERSION}}return false}},Sammy:{icon:"sammy",url:"http://sammyjs.org",test:function(win){if(win.Sammy&&win.Sammy.Application.curry){return{version:win.Sammy.VERSION||UNKNOWN_VERSION}}return false}},Rico:{icon:"rico",url:"http://openrico.sourceforge.net/examples/index.html",test:function(win){if(win.Rico){return{version:win.Rico.Version||UNKNOWN_VERSION}}return false}},MochiKit:{icon:"mochikit",url:"https://mochi.github.io/mochikit/",test:function(win){if(win.MochiKit&&win.MochiKit.Base.module){return{version:MochiKit.VERSION||UNKNOWN_VERSION}}return false}},"gRapha&euml;l":{icon:"graphael",url:"http://g.raphaeljs.com",test:function(win){if(win.Raphael&&win.Raphael.fn.g){return{version:UNKNOWN_VERSION}}return false}},Glow:{icon:"glow",url:"http://www.bbc.co.uk/glow",test:function(win){if(win.gloader){return{version:UNKNOWN_VERSION}}else if(win.glow&&win.glow.dom){return{version:win.glow.VERSION||UNKNOWN_VERSION}}else if(win.Glow){return{version:win.Glow.version||UNKNOWN_VERSION}}return false}},"Socket.IO":{icon:"socketio",url:"http://socket.io",test:function(win){if(win.io&&(win.io.sockets||win.io.Socket)){return{version:win.io.version||UNKNOWN_VERSION}}return false}},Mustache:{icon:"mustache",url:"http://mustache.github.com",test:function(win){if(win.Mustache&&win.Mustache.to_html){return{version:win.Mustache.version||UNKNOWN_VERSION}}return false}},"Fabric.js":{icon:"icon_48",url:"http://fabricjs.com/",test:function(win){if(win.fabric&&win.fabric.util){return{version:win.fabric.version||UNKNOWN_VERSION}}return false}},FuseJS:{icon:"fusejs",url:"http://kiro.me/projects/fuse.html",test:function(win){if(win.fuse){return{version:win.fuse.version||UNKNOWN_VERSION}}return false}},"Tween.js":{icon:"icon_48",url:"https://github.com/sole/tween.js",test:function(win){if(win.TWEEN&&win.TWEEN.Easing){return{version:UNKNOWN_VERSION}}return false}},SproutCore:{icon:"sproutcore",url:"http://www.sproutcore.com",test:function(win){if(win.SC&&win.SC.Application){return{version:UNKNOWN_VERSION}}return false}},"Zepto.js":{icon:"zepto",url:"http://zeptojs.com",test:function(win){if(win.Zepto&&win.Zepto.fn){return{version:UNKNOWN_VERSION}}return false}},"three.js":{icon:"icon_48",url:"http://threejs.org/",test:function(win){if(win.THREE&&win.THREE.REVISION){return{version:"r"+win.THREE.REVISION}}else if(win.THREE){return{version:UNKNOWN_VERSION}}return false}},PhiloGL:{icon:"philogl",url:"http://www.senchalabs.org/philogl/",test:function(win){if(win.PhiloGL&&win.PhiloGL.Camera){return{version:win.PhiloGL.version||UNKNOWN_VERSION}}return false}},CamanJS:{icon:"camanjs",url:"http://camanjs.com/",test:function(win){if(win.Caman&&win.Caman.version){return{version:win.Caman.version.release}}else if(win.Caman){return{version:UNKNOWN_VERSION}}return false}},yepnope:{icon:"yepnope",url:"http://yepnopejs.com/",test:function(win){if(win.yepnope){return{version:UNKNOWN_VERSION}}return false}},LABjs:{icon:"icon_48",url:"http://labjs.com/",test:function(win){if(win.$LAB){return{version:UNKNOWN_VERSION}}return false}},"Head JS":{icon:"headjs",url:"http://headjs.com/",test:function(win){if(win.head&&win.head.js){return{version:UNKNOWN_VERSION}}return false}},ControlJS:{icon:"icon_48",url:"http://stevesouders.com/controljs/",test:function(win){if(win.CJS&&win.CJS.start){return{version:UNKNOWN_VERSION}}return false}},RequireJS:{icon:"requirejs",url:"http://requirejs.org/",test:function(win){var req=win.require||win.requirejs;if(req&&(req.load||req.s&&req.s.contexts&&req.s.contexts._&&(req.s.contexts._.loaded||req.s.contexts._.load))){return{version:req.version||UNKNOWN_VERSION}}return false}},RightJS:{icon:"rightjs",url:"http://rightjs.org/",test:function(win){if(win.RightJS&&win.RightJS.isNode){return{version:win.RightJS.version||UNKNOWN_VERSION}}return false}},"jQuery Tools":{icon:"jquerytools",url:"http://jquerytools.github.io/",test:function(win){var jq=win.jQuery||win.$;if(jq&&jq.tools){return{version:jq.tools.version||UNKNOWN_VERSION}}return false}},Pusher:{icon:"pusher",url:"http://pusher.com/docs/pusher_js/",test:function(win){if(win.Pusher&&win.Pusher.Channel){return{version:win.Pusher.VERSION||UNKNOWN_VERSION}}return false}},"Paper.js":{icon:"paperjs",url:"http://paperjs.org/",test:function(win){if(win.paper&&win.paper.Point){return{version:win.paper.version||UNKNOWN_VERSION}}return false}},Swiffy:{icon:"icon_48",url:"http://www.google.com/doubleclick/studio/swiffy/",test:function(win){if(win.swiffy){return{version:UNKNOWN_VERSION}}return false}},Move:{icon:"move",url:"https://github.com/rsms/move",test:function(win){if(win.move&&win.move.compile){return{version:win.move.version()||UNKNOWN_VERSION}}return false}},AmplifyJS:{icon:"amplifyjs",url:"http://amplifyjs.com/",test:function(win){if(win.amplify&&win.amplify.publish){return{version:UNKNOWN_VERSION}}return false}},"Popcorn.js":{icon:"popcornjs",url:"http://popcornjs.org/",test:function(win){if(win.Popcorn&&win.Popcorn.Events){return{version:win.Popcorn.version||UNKNOWN_VERSION}}return false}},D3:{icon:"d3",url:"http://d3js.org",test:function(win){if(win.d3&&win.d3.select){return{version:win.d3.version||UNKNOWN_VERSION}}return false}},Handlebars:{icon:"handlebars",url:"http://handlebarsjs.com/",test:function(win){if(win.Handlebars&&win.Handlebars.compile){return{version:win.Handlebars.VERSION||UNKNOWN_VERSION}}return false}},Knockout:{icon:"knockout",url:"http://knockoutjs.com/",test:function(win){if(win.ko&&win.ko.applyBindings){return{version:win.ko.version||UNKNOWN_VERSION}}return false}},Spine:{icon:"icon_48",url:"http://spinejs.com/",test:function(win){if(win.Spine&&win.Spine.Controller){return{version:win.Spine.version||UNKNOWN_VERSION}}return false}},"jQuery Mobile":{icon:"jquery_mobile",url:"http://jquerymobile.com/",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.mobile){return{version:jq.mobile.version||UNKNOWN_VERSION}}return false}},"WebFont Loader":{icon:"icon_48",url:"https://github.com/typekit/webfontloader",test:function(win){if(win.WebFont&&win.WebFont.load){return{version:UNKNOWN_VERSION}}return false}},Angular:{icon:"angular",url:"https://angular.io/",test:function(win){var ng=win.document.querySelector("[ng-version]");if(ng){return{version:ng.getAttribute("ng-version")||UNKNOWN_VERSION}}return false}},AngularJS:{icon:"angularjs",url:"http://angularjs.org",test:function(win){var ng=win.angular;if(ng&&ng.version&&ng.version.full){return{version:ng.version.full}}else if(ng){return{version:UNKNOWN_VERSION}}return false}},"Ember.js":{icon:"emberjs",url:"http://emberjs.com/",test:function(win){var ember=win.Ember||win.Em;if(ember&&ember.propertyDidChange){return{version:ember.VERSION||UNKNOWN_VERSION}}return false}},"Hammer.js":{icon:"hammerjs",url:"http://eightmedia.github.io/hammer.js/",test:function(win){var hammer=win.Hammer;if(hammer&&hammer.Pinch){return{version:hammer.VERSION||"&lt; 1.0.10"}}return false}},"Visibility.js":{icon:"icon_48",url:"https://github.com/ai/visibilityjs",test:function(win){var visibility=win.Visibility;if(visibility&&visibility.every){return{version:UNKNOWN_VERSION}}return false}},"Velocity.js":{icon:"icon_48",url:"http://velocityjs.org/",test:function(win){var jq=win.jQuery||win.$,velocity=jq?jq.Velocity:win.Velocity;if(velocity&&velocity.RegisterEffect&&velocity.version){return{version:velocity.version.major+"."+velocity.version.minor+"."+velocity.version.patch}}else if(velocity&&velocity.RegisterEffect){return{version:UNKNOWN_VERSION}}return false}},"IfVisible.js":{icon:"icon_48",url:"http://serkanyersen.github.io/ifvisible.js/",test:function(win){var iv=win.ifvisible;if(iv&&iv.__ceGUID==="ifvisible.object.event.identifier"){return{version:UNKNOWN_VERSION}}return false}},"Pixi.js":{icon:"pixi",url:"https://github.com/GoodBoyDigital/pixi.js",test:function(win){var px=win.PIXI;if(px&&px.WebGLRenderer&&px.VERSION){return{version:px.VERSION.replace("v","")||UNKNOWN_VERSION}}return false}},"DC.js":{icon:"icon_48",url:"http://dc-js.github.io/dc.js/",test:function(win){var dc=win.dc;if(dc&&dc.registerChart){return{version:dc.version||UNKNOWN_VERSION}}return false}},"Greensock JS":{icon:"greensock",url:"https://github.com/greensock/GreenSock-JS",test:function(win){var gs=win.TweenMax||win.TweenLite;if(gs){return{version:gs.version||UNKNOWN_VERSION}}return false}},FastClick:{icon:"fastclick",url:"https://github.com/ftlabs/fastclick",test:function(win){if(win.FastClick&&win.FastClick.notNeeded){return{version:UNKNOWN_VERSION}}return false}},Isotope:{icon:"isotope",url:"http://isotope.metafizzy.co/",test:function(win){var iso=win.Isotope||win.$!=null&&win.$.Isotope;if(iso){return{version:UNKNOWN_VERSION}}return false}},Marionette:{icon:"marionette",url:"http://marionettejs.com/",test:function(win){if(win.Marionette&&win.Marionette.Application){return{version:win.Marionette.VERSION||UNKNOWN_VERSION}}return false}},Can:{icon:"icon_48",url:"http://canjs.com/",test:function(win){if(win.can&&win.can.Construct){return{version:win.can.VERSION||UNKNOWN_VERSION}}return false}},Vue:{icon:"vue",url:"http://vuejs.org/",test:function(win){if(win.Vue&&win.Vue.nextTick){return{version:win.Vue.version||UNKNOWN_VERSION}}return false}},Two:{icon:"two",url:"https://jonobr1.github.io/two.js",test:function(win){if(win.Two&&win.Two.Utils){return{version:win.Two.Version||UNKNOWN_VERSION}}return false}},Brewser:{icon:"brewser",url:"http://handcraftedldn.github.io/brewser/",test:function(win){if(win.BREWSER&&win.BREWSER.ua){return{version:BREWSER.VERSION||UNKNOWN_VERSION}}return false}},"Material Design Lite":{icon:"mdl",url:"http://www.getmdl.io/",test:function(win){if(win.componentHandler&&win.componentHandler.upgradeElement){return{version:UNKNOWN_VERSION}}return false}},"Kendo UI":{icon:"kendoui",url:"https://github.com/telerik/kendo-ui-core",test:function(win){if(win.kendo&&win.kendo.View&&win.kendo.View.extend){return{version:win.kendo.version||UNKNOWN_VERSION}}return false}},"Matter.js":{icon:"matter-js",url:"http://brm.io/matter-js/",test:function(win){if(win.Matter&&win.Matter.Engine){return{version:UNKNOWN_VERSION}}return false}},Riot:{icon:"riot",url:"http://riotjs.com/",test:function(win){if(win.riot&&win.riot.mixin){return{version:win.riot.version||UNKNOWN_VERSION}}return false}},"Sea.js":{icon:"icon_48",url:"http://seajs.org/",test:function(win){if(win.seajs&&win.seajs.use){return{version:win.seajs.version||UNKNOWN_VERSION}}return false}},"Moment.js":{icon:"momentjs",url:"http://momentjs.com/",test:function(win){if(win.moment&&(win.moment.isMoment||win.moment.lang)){return{version:win.moment.version||UNKNOWN_VERSION}}return false}},"Moment Timezone":{icon:"momentjs",url:"http://momentjs.com/timezone/",test:function(win){if(win.moment&&win.moment.tz){return{version:win.moment.tz.version||UNKNOWN_VERSION}}return false}},ScrollMagic:{icon:"scrollmagic",url:"http://scrollmagic.io/",test:function(win){if(win.ScrollMagic&&win.ScrollMagic.Controller){return{version:ScrollMagic.version||UNKNOWN_VERSION}}return false}},SWFObject:{icon:"icon_48",url:"https://github.com/swfobject/swfobject",test:function(win){if(win.swfobject&&win.swfobject.embedSWF){return{version:win.swfobject.version||UNKNOWN_VERSION}}else if(win.deconcept&&win.deconcept.SWFObject){return{version:UNKNOWN_VERSION}}return false}},FlexSlider:{icon:"icon_48",url:"https://woocommerce.com/flexslider/",test:function(win){var jq=win.jQuery||win.$||win.$jq||win.$j;if(jq&&jq.fn&&jq.fn.jquery&&jq.flexslider){return{version:UNKNOWN_VERSION}}return false}},SPF:{icon:"icon_48",url:"https://youtube.github.io/spfjs/",test:function(win){if(win.spf&&win.spf.init){return{version:UNKNOWN_VERSION}}return false}},"Numeral.js":{icon:"icon_48",url:"http://numeraljs.com/",test:function(win){if(win.numeral&&win.isNumeral){return{version:win.numeral.version||UNKNOWN_VERSION}}return false}},"boomerang.js":{icon:"icon_48",url:"https://soasta.github.io/boomerang/doc/",test:function(win){if(win.BOOMR&&win.BOOMR.utils&&win.BOOMR.init){return{version:win.BOOMR.version||UNKNOWN_VERSION}}return false}}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take a look at how we do the accessibility gatherer. we readFileSync the axe.min.js from the axe-core node module.

this way, versioning is pretty straightfoward as its just a node module dep bump.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two concerns about the this PR's approach (vs what @ebidel had sketched out in #1948):

  • Since gatherers run serially, this puts an API endpoint in our critical path. While we block Lighthouse execution on requests in other gatherers, this will be the first one that's not the developer's fault, i.e. not the fault of a resource from the site itself.

  • Currently our FAQ has

    "Lighthouse runs locally, auditing a page using a local version of the Chrome browser installed the machine. Report results are never processed or beaconed to a remote server."

    While this is limited to just sending npm packages and their version numbers, that wouldn't be true anymore after this change.

#1948 seemed to lean more toward just including the Snyk database. While that would likely be larger and it looks like the db is updated less often than the service, it would allow vulnerabilities to be tested entirely locally.

There wasn't a lot of discussion in #1948 about implementation approaches, so I'd be interested in discussing the tradeoffs so everyone knows what we're getting into (I'm sure all of this has come up before for some of you, but not all of us :)

@ebidel
Copy link
Contributor

ebidel commented May 27, 2017

@brendankenny when I was working on integrating HTTPArchive data into the report, I came up with a system that users opt'd into for pulling live data vs. using cached data. For "live" mode, running LH would pull from a live endpoint and cache the data. Subsequent runs of LH would use the cache for 24hrs (also easy to increase). For "offline" mode, LH would use a checked in version of the data. We could rev that per release or something.

Something opt'in might be nice for users that want the most up to date information. But agreed, an opt in soln would be good. A caching layer at the very least.

@brendankenny
Copy link
Member

what's the right way to move forward in that case? An offline solution with manual dependency updates for now, and then it sounds like @ebidel you've taken a look at a datasource update mechanism, so we could maybe write it as a general service that audits like this one could use?

Though it's worth noting the difference between checking via the API as is currently in the PR and

For "live" mode, running LH would pull from a live endpoint and cache the data

basically pulling data to locally check vs sending data to a service to check it remotely

@ebidel
Copy link
Contributor

ebidel commented May 30, 2017

basically pulling data to locally check

+1 we should play it safe. Pull data, never send it.

@tkadlec
Copy link
Contributor Author

tkadlec commented Jun 5, 2017

Ok...just wanted to let the dust settle. :)

+1 we should play it safe. Pull data, never send it.

So do we want to ditch the API call? Just did that for simplicity. We could also provide a link to a JSON version of our DB (without all the unnecessary languages). That could be pulled in periodically and would be more up to date that the DB @brendankenny found.

That way, nothing is sent externally. The libraries are tested internally against the most recent copy of the JSON file and you report the vuln information discovered. Sound like a plan?

@ebidel
Copy link
Contributor

ebidel commented Jun 5, 2017

@tkadlec sounds reasonable to bring in the data as a dep and cross reference it. https://github.com/snyk/vulnerabilitydb/tree/master/data/npm looks like it's updated ~monthly, so we could latch onto that timeline for our updates. It also looks like a bunch of individual json data files. Will we need a tool that aggregates them into a single file? For our binary size, I'd be curious how big that gets.

@tkadlec
Copy link
Contributor Author

tkadlec commented Jun 5, 2017

@ebidel Oh, just to clarify...I don't think you should pull from https://github.com/snyk/vulnerabilitydb/tree/master/data/npm. It updates slowly and brings unnecessary overhead.

What I'm proposing is a JSON file (hosted on S3) that is already flattened and excludes unnecessary languages/etc. We do this already for several partners we work with...so it's no problem to have one for Lighthouse either. That keeps it light and pruned, and updated each time we publish a new vuln.

You folks could decide how aggressive you want to be in pulling in a new version (looking at modified date, or on some regular time cadence).

@ebidel
Copy link
Contributor

ebidel commented Jun 5, 2017

Oh, gotcha. So it would be "offline" in the sense that we'd cache your endpoint per LH release. That's the same approach I was taking for http archive integration. I setup an endpoint that hosts the latest snapshot: https://lighthouse-viewer.appspot.com/data.

@tkadlec If it's easy, is that something you can setup and we can experiment with? It would be nice to have some testing before committing to something long term. You know, support and stuff :)

@tkadlec
Copy link
Contributor Author

tkadlec commented Jun 6, 2017

@ebidel: Definitely! I can have it setup tomorrow.

@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@paulirish
Copy link
Member

@googlebot shh baby its ok

I made a few rote changes. Boring stuff.

@paulirish
Copy link
Member

I think this is landable.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good!

this also needs a smoke/end-to-end test. Maybe we could take the do better web tester and adjust the CDN loaded version of jquery (already being used for an is-on-https check) so that it triggers a hit? The expected output would then go in dbw-expectations.js

}

/**
* @param {object} lib
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a more specific shape to these types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTG

}

/**
* @param {object} vulns
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTG

if (!libraries.length) {
return {
rawValue: true,
extendedInfo: {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need empty extendedInfo here? Can just leave off

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

static mostSevere(vulns) {
const sortedVulns = vulns
.map(vuln => {
vuln.numericSeverity = this.severityMap[vuln.severity];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can get rid of this map block by assigning numericSeverity up in getVulns()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @param {object} vulns
* @return {string}
*/
static mostSevere(vulns) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe call this highestSeverity since it's returning the highest severity level, not the most severe vulnerability? (at least that's how I interpreted mostSevere() :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Done.


url="https://snyk.io/partners/api/v2/vulndb/clientside.json"

wget "$url" -O snyk-snapshot2.json && mv snyk-snapshot2.json ./third-party
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add new line at end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -0,0 +1 @@
{"npm":{"angular":[{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10170"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<=1.1.5"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N","disclosureTime":"2013-06-20T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:00:00.000Z","modificationTime":"2016-11-01T14:08:59.890Z","creationTime":"2016-11-01T14:08:59.890Z","id":"npm:angular:20130621","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10170"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10179"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<1.2.0 >=1.0.0"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-21T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:10:00.000Z","modificationTime":"2016-11-01T15:35:22.355Z","creationTime":"2016-11-01T15:35:22.355Z","id":"npm:angular:20130622","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10179"]},{"title":"Arbitrary Script Injection","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10140"]},"severity":"high","semver":{"unaffected":[">=1.1.5"],"vulnerable":["<1.1.5"]},"credit":["Chirayu Krishnappa","Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","disclosureTime":"2013-06-24T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:20:00.000Z","modificationTime":"2016-11-01T12:48:50.251Z","creationTime":"2016-11-01T12:48:50.251Z","id":"npm:angular:20130625","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10140"]},{"title":"Protection Bypass","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10200"]},"severity":"high","semver":{"unaffected":[">=1.2.2"],"vulnerable":["<1.2.2"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2013-11-12T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:30:00.000Z","modificationTime":"2016-11-09T12:07:09.956Z","creationTime":"2016-11-09T12:07:09.956Z","id":"npm:angular:20131113","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10200"]},{"title":"Arbitrary Code Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10201"]},"severity":"low","semver":{"unaffected":[">=1.3.0"],"vulnerable":["<1.3.0"]},"credit":["Jann Horn"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","disclosureTime":"2014-06-07T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:40:00.000Z","modificationTime":"2016-11-09T12:23:07.035Z","creationTime":"2016-11-09T12:23:07.035Z","id":"npm:angular:20140608","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10201"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10191"]},"severity":"medium","semver":{"unaffected":[">=1.3.0-rc.4"],"vulnerable":["<1.3.0-rc.4"]},"credit":["Laurent Trillaud"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","disclosureTime":"2014-09-07T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:50:00.000Z","modificationTime":"2016-11-07T09:46:43.092Z","creationTime":"2016-11-07T09:46:43.092Z","id":"npm:angular:20140908","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10191"]},{"title":"Unsafe Object Deserialization","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10141"]},"severity":"high","semver":{"unaffected":[">=1.2.24"],"vulnerable":["<1.2.24 >=1.2.19"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2014-09-08T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:00:00.000Z","modificationTime":"2016-11-01T13:57:31.962Z","creationTime":"2016-11-01T13:57:31.962Z","id":"npm:angular:20140909","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10141"]},{"title":"Arbitrary Command Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10173"]},"severity":"medium","semver":{"unaffected":[">=1.3.2"],"vulnerable":["<1.3.2"]},"credit":["Sebastian Lekies","Jann Horn","Gábor Molnár"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:L","disclosureTime":"2014-11-03T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:10:00.000Z","modificationTime":"2016-11-01T12:33:38.496Z","creationTime":"2016-11-01T12:33:38.496Z","id":"npm:angular:20141104","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10173"]},{"title":"Arbitrary Code Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10174"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.2"],"vulnerable":["<1.5.0-beta.2"]},"credit":["Rodric Haddad"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2015-03-09T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:20:00.000Z","modificationTime":"2017-02-13T14:24:12.988Z","creationTime":"2016-11-01T14:24:12.988Z","id":"npm:angular:20150310","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10174"]},{"title":"JSONP Callback Attack","moduleName":"angular","packageName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10175"]},"severity":"medium","semver":{"vulnerable":["<1.6.1"],"unaffected":[">=1.6.1"]},"credit":["Pete Bacon Darwin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2015-03-14T22:00:00.000Z","patches":[],"publicationTime":"2017-02-13T18:30:00.000Z","modificationTime":"2017-02-13T14:36:18.735Z","creationTime":"2016-11-01T14:36:18.735Z","id":"npm:angular:20150315","alternativeIds":["SNYK-JS-ANGULAR-10175"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10176"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.0"],"vulnerable":["<1.5.0-beta.0 >=1.0.0"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-08-06T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:40:00.000Z","modificationTime":"2016-11-01T13:30:14.967Z","creationTime":"2016-11-01T13:30:14.967Z","id":"npm:angular:20150807","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10176"]},{"title":"Clickjacking","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-693"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10177"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-beta.0"],"vulnerable":["<1.5.0-beta.0 >=1.3.1"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N","disclosureTime":"2015-08-06T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:50:00.000Z","modificationTime":"2016-11-01T13:30:14.967Z","creationTime":"2016-11-01T13:30:14.967Z","id":"npm:angular:20150807-1","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10177"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10182"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.2"],"vulnerable":["<1.5.0-beta.2"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-09-08T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:00:00.000Z","modificationTime":"2016-11-02T08:40:11.750Z","creationTime":"2016-11-02T08:40:11.750Z","id":"npm:angular:20150909","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10182"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10180"]},"severity":"medium","semver":{"unaffected":[">=1.4.10"],"vulnerable":["<1.4.10"]},"credit":["Lucas Mirelmann"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2015-11-29T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:10:00.000Z","modificationTime":"2016-11-02T08:16:55.157Z","creationTime":"2016-11-02T08:16:55.157Z","id":"npm:angular:20151130","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10180"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10181"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-rc.0"],"vulnerable":["<1.5.0-rc.0"]},"credit":["Pete Bacon Darwin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2015-12-04T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:20:00.000Z","modificationTime":"2016-11-02T08:26:38.753Z","creationTime":"2016-11-02T08:26:38.753Z","id":"npm:angular:20151205","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10181"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10202"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-rc.2"],"vulnerable":["<1.5.0-rc.2 >=1.3.0"]},"credit":["Lucas Mirelmann"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2016-01-21T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:30:00.000Z","modificationTime":"2016-11-09T12:45:57.682Z","creationTime":"2016-11-09T12:45:57.682Z","id":"npm:angular:20160122","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10202"]},{"title":"Arbitrary Script Injection","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10203"]},"severity":"medium","semver":{"unaffected":[">=1.2.30"],"vulnerable":["<1.2.30 >=1.0.0"]},"credit":["Raphaël Jamet"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2016-05-26T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:40:00.000Z","modificationTime":"2016-11-09T13:00:18.135Z","creationTime":"2016-11-09T13:00:18.135Z","id":"npm:angular:20160527","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10203"]},{"title":"Content Security Policy (CSP) Bypass","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10190"]},"severity":"medium","semver":{"unaffected":[">=1.5.9"],"vulnerable":["<1.5.9 >=1.5.0"]},"credit":["Martin Probst"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N","disclosureTime":"2016-10-31T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:50:00.000Z","modificationTime":"2017-01-24T09:16:32.893Z","creationTime":"2016-11-07T09:16:32.893Z","id":"npm:angular:20161101","packageName":"angular","alternativeIds":["SNYK-JS-ANGULAR-10190"]}],"backbone":[{"title":"Cross Site Scripting","credit":[],"language":"js","packageManager":"npm","packageName":"backbone","moduleName":"backbone","semver":{"vulnerable":["<0.5.0"],"unaffected":[">=0.5.0"]},"identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-BACKBONE-10054"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/backbone/20110701/backbone_20110701_0_0_0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"],"version":"<0.5.0 >=0.3.3","modificationTime":"2015-11-06T02:09:36.180Z","comments":["https://github.com/jashkenas/backbone/commit/0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"],"id":"patch:npm:backbone:20110701:0"}],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","id":"npm:backbone:20110701","alternativeIds":["SNYK-JS-BACKBONE-10054"]},{"title":"Cross Site Scripting","credit":["Unknown"],"creationTime":"2016-05-24T06:45:20.086Z","modificationTime":"2016-05-24T06:45:20.086Z","publicationTime":"2016-06-22T17:50:20.000Z","disclosureTime":"2016-05-23T17:50:20.000Z","semver":{"vulnerable":["<= 0.3.3"],"unaffected":[">= 0.5.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":108,"ALTERNATIVE":["SNYK-JS-BACKBONE-10110"]},"patches":[],"moduleName":"backbone","language":"js","packageManager":"npm","id":"npm:backbone:20160523","packageName":"backbone","alternativeIds":["SNYK-JS-BACKBONE-10110"]}],"bootstrap":[{"title":"Cross-site Scripting (XSS)","credit":["Peter Corsaro"],"packageName":"bootstrap","moduleName":"bootstrap","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-BOOTSTRAP-10433"]},"semver":{"unaffected":[">=2.1.0"],"vulnerable":["<2.1.0"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2012-05-09T21:00:00.000Z","publicationTime":"2017-04-10T09:39:59.975Z","modificationTime":"2017-02-27T10:05:00.075Z","creationTime":"2017-02-27T10:05:00.075Z","id":"npm:bootstrap:20120510","alternativeIds":["SNYK-JS-BOOTSTRAP-10433"]}],"dojo":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<1.1"],"unaffected":[">=1.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2008-6681"],"ALTERNATIVE":["SNYK-JS-DOJO-10051"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20090409","packageName":"dojo","alternativeIds":["SNYK-JS-DOJO-10051"]},{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":[">=0.4 <0.4.4 || >=1.0 <1.0.3 || >=1.1 <1.1.2 || >=1.2 <1.2.4 || >=1.3 <1.3.3 || >=1.4 <1.4.2"],"unaffected":["<0.4 >=0.4.4 || <1.0 >=1.0.3 || <1.1 >=1.1.2 || <1.2 >=1.2.4 || <1.3 >=1.3.3 || <1.4 >=1.4.2"]},"CVSSv2":"CVSS:2.0/AV:N/AC:L/Au:N/C:C/I:C/A:C","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H","severity":"high","identifiers":{"CWE":["CWE-16"],"CVE":["CVE-2010-2276","CVE-2010-2272"],"ALTERNATIVE":["npm:dojo:20100614-1","npm:dojo:20100614-2","npm:dojo:20100614-3","npm:dojo:20100614-4","npm:dojo:20100614-5","SNYK-JS-DOJO-10052"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20100614","packageName":"dojo","alternativeIds":["npm:dojo:20100614-1","npm:dojo:20100614-2","npm:dojo:20100614-3","npm:dojo:20100614-4","npm:dojo:20100614-5","SNYK-JS-DOJO-10052"]},{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<1.4.2"],"unaffected":[">=1.4.2"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-2275"],"ALTERNATIVE":["SNYK-JS-DOJO-10053"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20100614-6","packageName":"dojo","alternativeIds":["SNYK-JS-DOJO-10053"]},{"title":"Cross Site Scripting","credit":["Unknown"],"creationTime":"2016-05-24T06:45:20.086Z","modificationTime":"2016-05-24T06:45:20.086Z","publicationTime":"2016-06-22T00:00:00.000Z","disclosureTime":"2016-05-23T16:48:27.000Z","semver":{"vulnerable":["<= 1.0.0"],"unaffected":[">= 1.1.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2008-6681"],"NSP":107,"ALTERNATIVE":["SNYK-JS-DOJO-10108"]},"patches":[],"moduleName":"dojo","language":"js","packageManager":"npm","id":"npm:dojo:20160523","packageName":"dojo","alternativeIds":["SNYK-JS-DOJO-10108"]}],"foundation-sites":[{"title":"Cross-site Scripting (XSS)","credit":["Mathieu Amiot"],"moduleName":"foundation-sites","packageName":"foundation-sites","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-FOUNDATIONSITES-10413"]},"semver":{"unaffected":[">=3.0.6"],"vulnerable":["<3.0.6 >=3.0.0"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2012-07-16T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.155Z","modificationTime":"2017-03-06T12:29:55.952Z","creationTime":"2017-03-06T12:29:55.952Z","id":"npm:foundation-sites:20120717","alternativeIds":["SNYK-JS-FOUNDATIONSITES-10413"]},{"title":"Cross-site Scripting (XSS)","credit":["Maya Kokits"],"moduleName":"foundation-sites","packageName":"foundation-sites","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-FOUNDATIONSITES-10414"]},"semver":{"unaffected":[">=5.5.3"],"vulnerable":["<5.5.3"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2015-06-18T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.227Z","modificationTime":"2017-03-06T12:57:37.670Z","creationTime":"2017-03-06T12:57:37.670Z","id":"npm:foundation-sites:20150619","alternativeIds":["SNYK-JS-FOUNDATIONSITES-10414"]}],"handlebars":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<=1.0.0-beta.3"],"unaffected":[">1.0.0-beta.3"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-HANDLEBARS-10047"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/handlebars/20110425/handlebars_20110425_0_0_b291a1ad8c9a33f834d126450635f0b6ca546a0c.patch"],"version":"<=1.0.0-beta.3","modificationTime":"2015-11-06T02:09:36.180Z","comments":["https://github.com/rgrove/handlebars.js/commit/b291a1ad8c9a33f834d126450635f0b6ca546a0c.patch"],"id":"patch:npm:handlebars:20110425:0"}],"moduleName":"handlebars","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:handlebars:20110425","packageName":"handlebars","alternativeIds":["SNYK-JS-HANDLEBARS-10047"]},{"title":"Content Injection (XSS)","credit":["Matias P. Brutti"],"semver":{"vulnerable":["<4.0.0"],"unaffected":[">=4.0.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":61,"ALTERNATIVE":["SNYK-JS-HANDLEBARS-10068"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/handlebars/20151207/handlebars_0.patch"],"version":"<4.0.0 >=3.0.2","modificationTime":"2015-12-14T23:52:16.811Z","comments":["https://github.com/wycats/handlebars.js/commit/83b8e846a3569bd366cf0b6bdc1e4604d1a2077e"],"id":"patch:npm:handlebars:20151207:0"}],"moduleName":"handlebars","creationTime":"2015-12-14T23:52:16.811Z","modificationTime":"2015-12-14T23:52:16.811Z","publicationTime":"2015-12-14T23:52:16.811Z","disclosureTime":"2015-12-07T16:52:07.962Z","language":"js","packageManager":"npm","id":"npm:handlebars:20151207","packageName":"handlebars","alternativeIds":["SNYK-JS-HANDLEBARS-10068"]}],"jquery":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2011-4969"],"ALTERNATIVE":["SNYK-JS-JQUERY-10183"]},"severity":"medium","semver":{"unaffected":[">=1.6.3"],"vulnerable":["<1.6.3"]},"credit":["Dave Methvin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2011-06-05T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2016-11-06T15:25:26.117Z","creationTime":"2016-11-06T15:25:26.117Z","id":"npm:jquery:20110606","packageName":"jquery","alternativeIds":["SNYK-JS-JQUERY-10183"]},{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"ALTERNATIVE":["SNYK-JS-JQUERY-10184"]},"severity":"medium","semver":{"unaffected":[">=1.9.0"],"vulnerable":["<1.9.0 >=1.7.1"]},"credit":["Richard Gibson"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-06-19T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2017-03-12T14:17:57.686Z","creationTime":"2016-11-06T13:53:57.686Z","id":"npm:jquery:20120206","packageName":"jquery","alternativeIds":["SNYK-JS-JQUERY-10184"]},{"title":"DOM Based Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2014-6071"],"ALTERNATIVE":["SNYK-JS-JQUERY-10185"]},"severity":"medium","semver":{"unaffected":[">=1.6.2"],"vulnerable":["<=1.5.1 >=1.4.2"]},"credit":["Mauro Risonho de Paula Assumpção"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2014-09-01T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2016-10-06T14:16:53.138Z","creationTime":"2016-11-06T14:16:53.138Z","id":"npm:jquery:20140902","packageName":"jquery","alternativeIds":["SNYK-JS-JQUERY-10185"]},{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-JQUERY-10186"]},"severity":"medium","semver":{"unaffected":[">=3.0.0-beta1 || >=1.12.0 <1.12.3"],"vulnerable":["<3.0.0-beta1 >1.12.3 || <1.12.0 >=1.4.0"]},"credit":["Egor Homakov"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2015-06-26T21:00:00.000Z","patches":[],"publicationTime":"2016-11-27T00:00:00.000Z","modificationTime":"2017-03-27T15:12:44.538Z","creationTime":"2016-11-06T15:12:44.538Z","id":"npm:jquery:20150627","packageName":"jquery","alternativeIds":["SNYK-JS-JQUERY-10186"]},{"title":"Denial of Service (DoS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-JQUERY-10187"]},"severity":"low","semver":{"unaffected":[">=3.0.0"],"vulnerable":["<3.0.0 >=2.1.0-beta1"]},"credit":["Michał Gołębiowski"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","disclosureTime":"2016-05-28T21:00:00.000Z","patches":[],"publicationTime":"2016-12-26T15:37:35.224Z","modificationTime":"2016-12-26T15:37:35.224Z","creationTime":"2016-11-06T15:37:35.224Z","id":"npm:jquery:20160529","packageName":"jquery","alternativeIds":["SNYK-JS-JQUERY-10187"]}],"jquery-mobile":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery-mobile","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-JQUERYMOBILE-10199"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<1.2.0"]},"credit":["Masato Kinugawa"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","disclosureTime":"2012-08-01T21:00:00.000Z","patches":[],"publicationTime":"2016-12-26T11:28:34.624Z","modificationTime":"2016-12-26T11:28:34.624Z","creationTime":"2016-11-09T11:28:34.624Z","id":"npm:jquery-mobile:20120802","packageName":"jquery-mobile","alternativeIds":["SNYK-JS-JQUERYMOBILE-10199"]}],"jquery-ui":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery-ui","packageName":"jquery-ui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-5312"],"ALTERNATIVE":["SNYK-JS-JQUERYUI-10188"]},"severity":"medium","semver":{"unaffected":[">=1.10.0"],"vulnerable":["<1.10.0"]},"credit":["shadowman131"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2010-09-02T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T14:37:13.516Z","modificationTime":"2017-02-13T14:37:13.516Z","creationTime":"2016-12-26T14:37:13.516Z","id":"npm:jquery-ui:20100903","alternativeIds":["SNYK-JS-JQUERYUI-10188"]},{"title":"Cross-site Scripting (XSS) via Tooltip","moduleName":"jquery-ui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2012-6662"],"ALTERNATIVE":["SNYK-JS-JQUERYUI-10189"]},"severity":"medium","semver":{"unaffected":[">=1.10.0"],"vulnerable":["<1.10.0"]},"credit":["Scott González"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2012-11-26T22:00:00.000Z","patches":[],"publicationTime":"2016-12-26T15:04:27.065Z","modificationTime":"2016-12-26T15:04:27.065Z","creationTime":"2016-11-06T15:04:27.065Z","id":"npm:jquery-ui:20121127","packageName":"jquery-ui","alternativeIds":["SNYK-JS-JQUERYUI-10189"]},{"title":"XSS in dialog closeText","credit":["Phat Ly"],"creationTime":"2016-07-22T00:00:02.715Z","modificationTime":"2016-07-22T00:00:02.715Z","publicationTime":"2016-07-21T22:21:41.000Z","disclosureTime":"2016-07-21T22:21:41.000Z","semver":{"vulnerable":["<=1.11.4"],"unaffected":[">=1.12.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","severity":"high","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":127,"ALTERNATIVE":["SNYK-JS-JQUERYUI-10118"]},"patches":[],"moduleName":"jquery-ui","language":"js","packageManager":"npm","id":"npm:jquery-ui:20160721","packageName":"jquery-ui","alternativeIds":["SNYK-JS-JQUERYUI-10118"]}],"knockout":[{"title":"Cross-site Scripting (XSS)","credit":["Steven Sanderson"],"moduleName":"knockout","packageName":"knockout","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-KNOCKOUT-10415"]},"semver":{"unaffected":[">=3.0.0"],"vulnerable":["<3.0.0 >=2.1.0-pre"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-30T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.295Z","modificationTime":"2017-03-01T12:39:34.669Z","creationTime":"2017-03-01T12:39:34.669Z","id":"npm:knockout:20130701","alternativeIds":["SNYK-JS-KNOCKOUT-10415"]}],"moment":[{"title":"Regular Expression Denial of Service (DoS)","credit":["Adam Baldwin"],"creationTime":"2016-02-01T19:00:03.862Z","modificationTime":"2016-09-28T19:00:03.862Z","publicationTime":"2016-02-01T19:00:03.862Z","semver":{"vulnerable":["<=2.11.1"],"unaffected":[">2.11.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","severity":"low","identifiers":{"CWE":["CWE-400"],"CVE":[],"NSP":55,"ALTERNATIVE":["SNYK-JS-MOMENT-10084"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_0_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.11.1 >2.10.6","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:0"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_1_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.10.6 >2.9.0","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:1"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_2_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.9.0 >2.2.1","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:2"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_3_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"=2.2.1","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:3"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_4_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<2.2.1 >2.0.0","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:4"}],"moduleName":"moment","disclosureTime":"2016-01-26T20:04:21.225Z","language":"js","packageManager":"npm","id":"npm:moment:20160126","packageName":"moment","alternativeIds":["SNYK-JS-MOMENT-10084"]},{"title":"Regular Expression Denial of Service (DoS)","moduleName":"moment","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-400"],"CVE":[],"ALTERNATIVE":["SNYK-JS-MOMENT-10164"]},"semver":{"vulnerable":["<2.15.2"],"unaffected":[">=2.15.2"]},"credit":["Snyk Security Research Team"],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H","disclosureTime":"2016-10-18T21:00:00.000Z","patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20161019/moment_20161019_0_1.patch"],"version":"<2.15.2 >=2.14.0","modificationTime":"2016-10-24T00:00:00.000Z","comments":[],"id":"patch:npm:moment:20161019:0"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20161019/moment_20161019_0_0.patch"],"version":"<2.14.0 >=2.12.0","modificationTime":"2016-10-24T00:00:00.000Z","comments":[],"id":"patch:npm:moment:20161019:1"}],"publicationTime":"2016-10-24T06:57:59.675Z","modificationTime":"2016-10-23T06:57:59.675Z","creationTime":"2016-10-23T06:57:59.675Z","id":"npm:moment:20161019","packageName":"moment","alternativeIds":["SNYK-JS-MOMENT-10164"]}],"mustache":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["< 0.3.1"],"unaffected":[">= 0.3.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-MUSTACHE-10046"]},"patches":[],"moduleName":"mustache","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:mustache:20110814","packageName":"mustache","alternativeIds":["SNYK-JS-MUSTACHE-10046"]},{"title":"Content Injection due to quoteless attributes","credit":["Matias P. Brutti"],"semver":{"vulnerable":["<2.2.1"],"unaffected":[">=2.2.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":62,"ALTERNATIVE":["SNYK-JS-MUSTACHE-10067"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/mustache/20151207/mustache_0.patch"],"version":"<2.2.1 >=2.1.0","modificationTime":"2015-12-14T23:52:16.806Z","comments":["https://github.com/janl/mustache.js/commit/378bcca8a5cfe4058f294a3dbb78e8755e8e0da5"],"id":"patch:npm:mustache:20151207:0"}],"moduleName":"mustache","creationTime":"2015-12-14T23:52:16.806Z","modificationTime":"2015-12-14T23:52:16.806Z","publicationTime":"2015-12-14T23:52:16.806Z","disclosureTime":"2015-12-07T17:13:57.565Z","language":"js","packageManager":"npm","id":"npm:mustache:20151207","packageName":"mustache","alternativeIds":["SNYK-JS-MUSTACHE-10067"]}],"react":[{"title":"Cross-site Scripting (XSS)","moduleName":"react","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-7035"],"ALTERNATIVE":["SNYK-JS-REACT-10192"]},"severity":"medium","semver":{"unaffected":[">=0.5.2 || <=0.3.x || =0.4.2"],"vulnerable":[">=0.5.0 <0.5.2 || >=0.4.0 <0.4.2"]},"credit":["Paul O’Shannessy","Thomas Aylott"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","disclosureTime":"2013-12-16T22:00:00.000Z","patches":[],"publicationTime":"2017-01-18T14:00:21.094Z","modificationTime":"2016-11-08T08:23:21.094Z","creationTime":"2016-11-08T08:23:21.094Z","id":"npm:react:20131217","packageName":"react","alternativeIds":["SNYK-JS-REACT-10192"]},{"title":"Cross-site Scripting (XSS)","moduleName":"react","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-REACT-10193"]},"severity":"high","semver":{"unaffected":[">=0.14.0"],"vulnerable":["<0.14.0"]},"credit":["Daniel LeCheminant"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-03-17T22:00:00.000Z","patches":[],"publicationTime":"2017-01-18T14:00:38.403Z","modificationTime":"2016-11-08T09:59:38.403Z","creationTime":"2016-11-08T09:59:38.403Z","id":"npm:react:20150318","packageName":"react","alternativeIds":["SNYK-JS-REACT-10193"]}],"riot":[{"title":"Cross-site Scripting (XSS)","credit":["crazy2be"],"moduleName":"riot","packageName":"riot","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-RIOT-10447"]},"semver":{"unaffected":[">=0.9.6"],"vulnerable":["<0.9.6"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2013-11-13T22:00:00.000Z","publicationTime":"2017-05-08T12:34:46.386Z","modificationTime":"2017-03-20T14:44:23.092Z","creationTime":"2017-03-20T14:44:23.092Z","id":"npm:riot:20131114","alternativeIds":["SNYK-JS-RIOT-10447"]}],"socket.io":[{"title":"Insecure Randomness","credit":["Martin Thomson"],"moduleName":"socket.io","packageName":"socket.io","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-330"],"CVE":[],"ALTERNATIVE":["SNYK-JS-SOCKETIO-10397"]},"semver":{"unaffected":[">=0.9.7"],"vulnerable":["<0.9.7"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","disclosureTime":"2012-03-22T22:00:00.000Z","publicationTime":"2017-02-13T13:46:59.513Z","modificationTime":"2017-02-13T13:46:59.513Z","creationTime":"2017-02-01T13:46:59.513Z","id":"npm:socket.io:20120323","alternativeIds":["SNYK-JS-SOCKETIO-10397"]},{"title":"Cross-site Scripting (XSS)","credit":["Almog Melamed"],"moduleName":"socket.io","packageName":"socket.io","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-SOCKETIO-10398"]},"semver":{"unaffected":[">=0.9.6"],"vulnerable":["<0.9.6"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-04-16T21:00:00.000Z","publicationTime":"2017-02-13T13:28:52.754Z","modificationTime":"2017-02-13T13:28:52.754Z","creationTime":"2017-02-01T13:28:52.754Z","id":"npm:socket.io:20120417","alternativeIds":["SNYK-JS-SOCKETIO-10398"]}],"yui":[{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-4207"],"ALTERNATIVE":["SNYK-JS-YUI-10383"]},"severity":"medium","semver":{"unaffected":[">=2.8.2 || <2.4.0"],"vulnerable":["<2.8.2 >=2.4.0"]},"credit":["Unknown"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2010-10-24T22:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:24:55.944Z","modificationTime":"2017-01-22T09:24:55.944Z","creationTime":"2017-01-22T09:24:55.944Z","id":"npm:yui:20101025","alternativeIds":["SNYK-JS-YUI-10383"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-YUI-10384"]},"severity":"medium","semver":{"unaffected":[">=3.5.1 || <3.5.0-PR1"],"vulnerable":["<3.5.1 >=3.5.0-PR1"]},"credit":["Ryan Grove"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-04-27T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:12:40.841Z","modificationTime":"2017-02-13T09:12:40.841Z","creationTime":"2017-01-22T09:12:40.841Z","id":"npm:yui:20120428","alternativeIds":["SNYK-JS-YUI-10384"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2012-5881","CVE-2012-5882","CVE-2012-5883"],"ALTERNATIVE":["SNYK-JS-YUI-10385"]},"severity":"medium","semver":{"unaffected":[">=3.0.0 || <2.4.0"],"vulnerable":["<3.0.0 >=2.4.0"]},"credit":["Unknwon"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-10-29T22:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:20:03.679Z","modificationTime":"2017-02-13T09:20:03.679Z","creationTime":"2017-01-22T09:20:03.679Z","id":"npm:yui:20121030","alternativeIds":["SNYK-JS-YUI-10385"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-4941"],"ALTERNATIVE":["SNYK-JS-YUI-10386"]},"severity":"medium","semver":{"unaffected":[">=3.10.0 || <3.0.0"],"vulnerable":["<3.10.0 >=3.0.0"]},"credit":["Aleksandr Dobkin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-05-14T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T08:54:05.822Z","modificationTime":"2017-02-13T08:54:05.822Z","creationTime":"2017-01-22T08:54:05.822Z","id":"npm:yui:20130515","alternativeIds":["SNYK-JS-YUI-10386"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-4940"],"ALTERNATIVE":["SNYK-JS-YUI-10387"]},"severity":"medium","semver":{"unaffected":[">=3.10.3 <3.10.2"],"vulnerable":["=3.10.2"]},"credit":["Unknown"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-03T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:01:24.863Z","modificationTime":"2017-02-13T09:01:24.863Z","creationTime":"2017-01-22T09:01:24.863Z","id":"npm:yui:20130604","alternativeIds":["SNYK-JS-YUI-10387"]}]}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we nest this file so it's in third-party/snyk/snapshot.json (or whatever filename)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Done. :)

@brendankenny
Copy link
Member

also, would you mind maybe rebasing so we get the bundlesize fix picked up?

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from me.

When brendan is good, we'll merge.

@tkadlec
Copy link
Contributor Author

tkadlec commented Sep 29, 2017

Added an end to end test as well. Think that's what @brendankenny had in mind.

load snykDB once
@brendankenny
Copy link
Member

added a minor change to a few of the jsdoc types and moved the json file from being reloaded every time the getter is called to only once

@brendankenny
Copy link
Member

and the end to end test is great :)

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☣️ 🔬 🚫

LGTM! Thank you for sticking with this verrrrry long process :)

@brendankenny brendankenny merged commit 6b4b8b9 into GoogleChrome:master Sep 29, 2017
@paulirish
Copy link
Member

OMG. We merged. 🤗

@patrickhulce
Copy link
Collaborator

woohoo! very well done @tkadlec many thanks!! 🎉 🍰 💯

@igrigorik
Copy link

Yay! Kudos for the awesome work, everyone. Can't wait to see this live.

@tkadlec
Copy link
Contributor Author

tkadlec commented Oct 2, 2017

Yay! Looking forward to seeing this out. :) Thanks for the patience!

@GoogleChrome GoogleChrome locked as spam and limited conversation to collaborators May 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.