Refactoring, allow multiple expressions per js field, remove env detection

main
Elbert Alias 7 years ago
parent 28d2afaa61
commit 66c703c2fa

@ -10436,6 +10436,9 @@
"cats": [
"12"
],
"js": {
"jQuery.fn.jquery": "^([\\d.]+)\\;version:\\1"
},
"env": "^jQuery$",
"icon": "jQuery.svg",
"script": [

@ -1,76 +1,58 @@
/** global: browser */
if ( typeof browser !== 'undefined' && typeof document.body !== 'undefined' ) {
var html = document.documentElement.outerHTML;
try {
var html = document.documentElement.outerHTML;
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
var scripts = Array.prototype.slice
const scripts = Array.prototype.slice
.apply(document.scripts)
.filter(s => s.src)
.map(s => s.src);
.filter(script => script.src)
.map(script => script.src);
try {
browser.runtime.sendMessage({
id: 'analyze',
subject: { html },
subject: { html, scripts },
source: 'content.js'
});
browser.runtime.sendMessage({
id: 'analyze',
subject: { scripts },
source: 'content.js'
});
var container = document.createElement('wappalyzerData');
container.setAttribute('id', 'wappalyzerData');
container.setAttribute('style', 'display: none');
var script = document.createElement('script');
script.setAttribute('id', 'wappalyzerEnvDetection');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
const script = document.createElement('script');
container.addEventListener('wappalyzerEnvEvent', (event => {
browser.runtime.sendMessage({
id: 'JS_ready',
subject: { },
source: 'content.js'
}, response => {
window.postMessage({patterns: response.patterns}, "*");
});
window.addEventListener('message', (event => {
if (event.data.js === undefined)
script.onload = () => {
addEventListener('message', event => {
if ( event.data.id !== 'js' ) {
return;
var js = event.data.js ;
}
browser.runtime.sendMessage({
id: 'analyze',
subject: { js },
subject: {
js: event.data.js
},
source: 'content.js'
});
}), true);
var env = event.target.childNodes[0].nodeValue;
}, true);
document.documentElement.removeChild(container);
document.documentElement.removeChild(script);
env = env.split(' ').slice(0, 500);
browser.runtime.sendMessage({
id: 'analyze',
subject: { env },
( chrome || browser ).runtime.sendMessage({
id: 'init_js',
subject: {},
source: 'content.js'
}, response => {
postMessage({
id: 'patterns',
patterns: response.patterns
}, '*');
});
}), true);
};
script.setAttribute('id', 'wappalyzer');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
document.documentElement.appendChild(container);
document.documentElement.appendChild(script);
} catch(e) {
document.body.appendChild(script);
} catch (e) {
log(e);
}
}

@ -74,7 +74,8 @@ fetch('../apps.json')
.then(json => {
wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories;
wappalyzer.parseJS();
wappalyzer.parseJsPatterns();
categoryOrder = Object.keys(wappalyzer.categories).sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority);
})
@ -193,9 +194,9 @@ browser.webRequest.onCompleted.addListener(request => {
};
break;
case 'JS_ready':
case 'init_js':
response = {
patterns: wappalyzer.parsedJS
patterns: wappalyzer.jsPatterns
};
break;

@ -1,43 +1,43 @@
(function() {
try {
var i, environmentVars = '', eEnv = document.createEvent('Events'), container = document.getElementById('wappalyzerData');
eEnv.initEvent('wappalyzerEnvEvent', true, false);
for ( i in window ) {
environmentVars += i + ' ';
}
container.appendChild(document.createComment(environmentVars));
container.dispatchEvent(eEnv);
window.addEventListener('message', (event => {
if (event.data.patterns === undefined)
return;
var properties = event.data.patterns;
var js = {};
Object.keys(properties).forEach(appname => {
Object.keys(properties[appname]).forEach(property => {
var content = false;
if( content = JSdetection(property) ){
if ( js[appname] === undefined )
js[appname] = {};
js[appname][property] = properties[appname][property];
js[appname][property]["content"] = content;
}
});
});
window.postMessage({js: js}, "*");
}), false);
} catch(e) {
// Fail quietly
}
addEventListener('message', (event => {
if ( event.data.id !== 'patterns' ) {
return;
}
const patterns = event.data.patterns || {};
const js = {};
Object.keys(patterns).forEach(appName => {
js[appName] = {};
Object.keys(patterns[appName]).forEach(chain => {
js[appName][chain] = {};
patterns[appName][chain].forEach((pattern, index) => {
const value = detect(chain);
if ( value ) {
js[appName][chain][index] = value;
}
});
});
});
postMessage({ id: 'js', js }, '*');
}), false);
} 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);
function detect(chain) {
const properties = chain.split('.');
const value = properties.reduce((parent, property) => {
return parent && parent.hasOwnProperty(property) ? parent[property] : null;
}, window);
return typeof value === 'string' ? value : !!value;
return typeof value === 'string' ? value : !!value;
}

@ -18,7 +18,7 @@ class Wappalyzer {
this.apps = {};
this.categories = {};
this.driver = {};
this.parsedJS = undefined;
this.jsPatterns = {};
this.detected = {};
this.hostnameCache = {};
@ -85,7 +85,7 @@ class Wappalyzer {
if ( data.js ) {
Object.keys(data.js).forEach(appName => {
this.analyzeJS(apps[appName], data.js[appName]);
this.analyzeJs(apps[appName], data.js[appName]);
});
}
@ -252,16 +252,14 @@ class Wappalyzer {
}
/**
* Parse JS patterns
* Parse JavaScript patterns
*/
parseJS() {
if ( this.parsedJS === undefined){
this.parsedJS = {};
Object.keys(this.apps).forEach(appName => {
if (this.apps[appName].js)
this.parsedJS[appName] = this.parsePatterns(this.apps[appName].js);
});
}
parseJsPatterns() {
Object.keys(this.apps).forEach(appName => {
if ( this.apps[appName].js ) {
this.jsPatterns[appName] = this.parsePatterns(this.apps[appName].js);
}
});
}
resolveExcludes(apps) {
@ -508,16 +506,17 @@ class Wappalyzer {
}
/**
* Analyze JS variables
* Analyze JavaScript 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);
}
analyzeJs(app, results) {
Object.keys(results).forEach(string => {
Object.keys(results[string]).forEach(index => {
const pattern = this.jsPatterns[app.name][string][index];
const value = results[string][index];
if ( pattern.regex.test(value) ) {
this.addDetected(app, pattern, 'js', value);
}
});
});
}