From c6b6df773d5d4976991935093d1466723e84eca0 Mon Sep 17 00:00:00 2001 From: Camille Barneaud Date: Tue, 12 Dec 2017 02:44:56 +0100 Subject: [PATCH] Add JS field in Wappalyzer.js & for WebExtension driver --- src/drivers/webextension/js/driver.js | 6 +++++ src/drivers/webextension/js/inject.js | 37 ++++++++++++++++++++++++++- src/wappalyzer.js | 36 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index e2a07a865..7ff66bd1c 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -191,6 +191,12 @@ browser.webRequest.onCompleted.addListener(request => { categories: wappalyzer.categories }; + break; + case 'JS_ready': + response = { + patterns: wappalyzer.parseJS() + }; + break; default: } diff --git a/src/drivers/webextension/js/inject.js b/src/drivers/webextension/js/inject.js index cc56a76c5..1efd19165 100644 --- a/src/drivers/webextension/js/inject.js +++ b/src/drivers/webextension/js/inject.js @@ -10,7 +10,42 @@ document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars)); document.getElementById('wappalyzerData').dispatchEvent(e); + + // Handle property match + browser.runtime.sendMessage({ + id: 'JS_ready', + subject: { }, + source: 'inject.js' + }, response => { + var properties = response.patterns; + var js = {}; + Object.keys(properties).forEach(app => { + Object.keys(properties[app]).forEach(property => { + if(var content = JSdetection(property)){ + if ( js[appname] === undefined ) { + js[appname] = {}; + } + js[appname][property] = properties[app][property]; + js[appname][property]["content"] = content; + } + }); + }); + browser.runtime.sendMessage({ + id: 'analyze', + subject: { js }, + source: 'inject.js' + }); + }); } catch(e) { // Fail quietly - } + } }()); + +function JSdetection(p){ + const objects = p.split('.'); + const value = objects.reduce((parent, property) => { + return parent && parent.hasOwnProperty(property) ? parent[property] : null; + }, window); + + return typeof value === 'string' ? value : !!value; +} \ No newline at end of file diff --git a/src/wappalyzer.js b/src/wappalyzer.js index bfa52fd66..d76e604f0 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -18,6 +18,7 @@ class Wappalyzer { this.apps = {}; this.categories = {}; this.driver = {}; + this.parsedJS = {}; this.detected = {}; this.hostnameCache = {}; @@ -82,6 +83,12 @@ class Wappalyzer { } }) + if ( data.js ) { + Object.keys(data.js).forEach(appName => { + this.analyzeJS(this.apps[appname], data.js[appname]) + }); + } + Object.keys(apps).forEach(appName => { var app = apps[appName]; @@ -244,6 +251,20 @@ class Wappalyzer { return parsed; } + /** + * Parse JS patterns + */ + parseJS() { + if ( this.parsedJS == {} ){ + Object.keys(this.apps).forEach(appName => { + if (apps[appName].props.js){ + parsedJS[appName] = this.parsePatterns(apps[appName].props.js); + } + }); + } + return this.parsedJS + } + resolveExcludes(apps) { var excludes = []; @@ -487,6 +508,21 @@ class Wappalyzer { } } + /** + * Analyze JS variables + */ + analyzeJS(app, js) { + Object.keys(js).forEach(property => { + var content = js[property]["content"]; + delete js[property]["content"]; + js[property].forEach(pattern => { + if ( pattern.regex.test(content) ) { + this.addDetected(app, pattern, 'js', content, property); + } + }); + }); + } + /** * Analyze robots.txt */