From 531f13519697bcfc5e31b70c122fab2b2a8346f2 Mon Sep 17 00:00:00 2001 From: Patrick Meenan Date: Tue, 19 Oct 2021 09:12:12 -0700 Subject: [PATCH 1/2] Correctly handle error response codes when a target disappears --- internal/devtools.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/devtools.py b/internal/devtools.py index 9c3f4b665..93f0cb69a 100644 --- a/internal/devtools.py +++ b/internal/devtools.py @@ -879,13 +879,15 @@ def send_command(self, method, params, wait=False, timeout=10, target_id=None): if wait: self.pending_commands.append(command_id) end_time = monotonic() + timeout - self.send_command('Target.sendMessageToTarget', + target_response = self.send_command('Target.sendMessageToTarget', {'targetId': target_id, 'message': json.dumps(msg)}, wait=wait, timeout=timeout) if wait: if command_id in self.command_responses: ret = self.command_responses[command_id] del self.command_responses[command_id] + elif target_response is None or 'error' in target_response: + ret = target_response else: while ret is None and monotonic() < end_time: try: From ccb502a91227f0b0dc548788556b52d8c1f84605 Mon Sep 17 00:00:00 2001 From: Patrick Meenan Date: Tue, 19 Oct 2021 14:10:10 -0700 Subject: [PATCH 2/2] Updated to latest Wappalyzer and fixed issues with apps that depend on other apps --- internal/devtools_browser.py | 15 +- internal/support/Wappalyzer/categories.json | 681 + internal/support/Wappalyzer/groups.json | 53 + internal/support/Wappalyzer/package.json | 35 + internal/support/Wappalyzer/script.js | 353 +- internal/support/Wappalyzer/technologies.json | 27687 ---------------- .../support/Wappalyzer/technologies/_.json | 98 + .../support/Wappalyzer/technologies/a.json | 2991 ++ .../support/Wappalyzer/technologies/b.json | 1395 + .../support/Wappalyzer/technologies/c.json | 2257 ++ .../support/Wappalyzer/technologies/d.json | 1078 + .../support/Wappalyzer/technologies/e.json | 1016 + .../support/Wappalyzer/technologies/f.json | 1149 + .../support/Wappalyzer/technologies/g.json | 1443 + .../support/Wappalyzer/technologies/h.json | 827 + .../support/Wappalyzer/technologies/i.json | 862 + .../support/Wappalyzer/technologies/j.json | 664 + .../support/Wappalyzer/technologies/k.json | 739 + .../support/Wappalyzer/technologies/l.json | 1056 + .../support/Wappalyzer/technologies/m.json | 1934 ++ .../support/Wappalyzer/technologies/n.json | 551 + .../support/Wappalyzer/technologies/o.json | 1157 + .../support/Wappalyzer/technologies/p.json | 2134 ++ .../support/Wappalyzer/technologies/q.json | 154 + .../support/Wappalyzer/technologies/r.json | 1294 + .../support/Wappalyzer/technologies/s.json | 4050 +++ .../support/Wappalyzer/technologies/t.json | 1564 + .../support/Wappalyzer/technologies/u.json | 465 + .../support/Wappalyzer/technologies/v.json | 652 + .../support/Wappalyzer/technologies/w.json | 1140 + .../support/Wappalyzer/technologies/x.json | 256 + .../support/Wappalyzer/technologies/y.json | 297 + .../support/Wappalyzer/technologies/z.json | 472 + internal/support/Wappalyzer/wappalyzer.js | 12 +- 34 files changed, 32671 insertions(+), 27860 deletions(-) create mode 100644 internal/support/Wappalyzer/categories.json create mode 100644 internal/support/Wappalyzer/groups.json create mode 100644 internal/support/Wappalyzer/package.json delete mode 100644 internal/support/Wappalyzer/technologies.json create mode 100644 internal/support/Wappalyzer/technologies/_.json create mode 100644 internal/support/Wappalyzer/technologies/a.json create mode 100644 internal/support/Wappalyzer/technologies/b.json create mode 100644 internal/support/Wappalyzer/technologies/c.json create mode 100644 internal/support/Wappalyzer/technologies/d.json create mode 100644 internal/support/Wappalyzer/technologies/e.json create mode 100644 internal/support/Wappalyzer/technologies/f.json create mode 100644 internal/support/Wappalyzer/technologies/g.json create mode 100644 internal/support/Wappalyzer/technologies/h.json create mode 100644 internal/support/Wappalyzer/technologies/i.json create mode 100644 internal/support/Wappalyzer/technologies/j.json create mode 100644 internal/support/Wappalyzer/technologies/k.json create mode 100644 internal/support/Wappalyzer/technologies/l.json create mode 100644 internal/support/Wappalyzer/technologies/m.json create mode 100644 internal/support/Wappalyzer/technologies/n.json create mode 100644 internal/support/Wappalyzer/technologies/o.json create mode 100644 internal/support/Wappalyzer/technologies/p.json create mode 100644 internal/support/Wappalyzer/technologies/q.json create mode 100644 internal/support/Wappalyzer/technologies/r.json create mode 100644 internal/support/Wappalyzer/technologies/s.json create mode 100644 internal/support/Wappalyzer/technologies/t.json create mode 100644 internal/support/Wappalyzer/technologies/u.json create mode 100644 internal/support/Wappalyzer/technologies/v.json create mode 100644 internal/support/Wappalyzer/technologies/w.json create mode 100644 internal/support/Wappalyzer/technologies/x.json create mode 100644 internal/support/Wappalyzer/technologies/y.json create mode 100644 internal/support/Wappalyzer/technologies/z.json diff --git a/internal/devtools_browser.py b/internal/devtools_browser.py index 104235b7a..4859530b3 100644 --- a/internal/devtools_browser.py +++ b/internal/devtools_browser.py @@ -990,10 +990,14 @@ def wappalyzer_script(self, response_headers, cookies): with open(os.path.join(self.support_path, 'Wappalyzer', 'wappalyzer.js')) as f_in: wappalyzer = f_in.read() if wappalyzer is not None: - json_data = None - with open(os.path.join(self.support_path, 'Wappalyzer', 'technologies.json')) as f_in: - json_data = f_in.read() - if json is not None: + technologies = {} + categories = {} + with io.open(os.path.join(self.support_path, 'Wappalyzer', 'categories.json'), 'r', encoding='utf-8') as f_in: + categories = json.load(f_in) + for filename in sorted(glob.glob(os.path.join(self.support_path, 'Wappalyzer', 'technologies', '*.json'))): + with io.open(filename, 'r', encoding='utf-8') as f_in: + technologies.update(json.load(f_in)) + if technologies and categories: # Format the headers as a dictionary of lists headers = {} if response_headers is not None: @@ -1019,9 +1023,10 @@ def wappalyzer_script(self, response_headers, cookies): headers[key] = [] headers[key].append(value) script = script.replace('%WAPPALYZER%', wappalyzer) - script = script.replace('%JSON%', json_data) script = script.replace('%COOKIES%', json.dumps(cookies)) script = script.replace('%RESPONSE_HEADERS%', json.dumps(headers)) + script = script.replace('%CATEGORIES%', json.dumps(categories)) + script = script.replace('%TECHNOLOGIES%', json.dumps(technologies)) except Exception: logging.exception('Error building wappalyzer script') return script diff --git a/internal/support/Wappalyzer/categories.json b/internal/support/Wappalyzer/categories.json new file mode 100644 index 000000000..d6e8c8bf7 --- /dev/null +++ b/internal/support/Wappalyzer/categories.json @@ -0,0 +1,681 @@ +{ + "1": { + "groups": [ + 3 + ], + "name": "CMS", + "priority": 1 + }, + "2": { + "groups": [ + 3, + 4, + 18 + ], + "name": "Message boards", + "priority": 1 + }, + "3": { + "groups": [ + 5 + ], + "name": "Database managers", + "priority": 2 + }, + "4": { + "groups": [ + 3 + ], + "name": "Documentation", + "priority": 2 + }, + "5": { + "groups": [ + 6 + ], + "name": "Widgets", + "priority": 9 + }, + "6": { + "groups": [ + 1 + ], + "name": "Ecommerce", + "priority": 1 + }, + "7": { + "groups": [ + 3, + 10 + ], + "name": "Photo galleries", + "priority": 1 + }, + "8": { + "groups": [ + 3 + ], + "name": "Wikis", + "priority": 1 + }, + "9": { + "groups": [ + 5, + 7 + ], + "name": "Hosting panels", + "priority": 1 + }, + "10": { + "groups": [ + 8 + ], + "name": "Analytics", + "priority": 9 + }, + "11": { + "groups": [ + 3 + ], + "name": "Blogs", + "priority": 1 + }, + "12": { + "groups": [ + 9 + ], + "name": "JavaScript frameworks", + "priority": 8 + }, + "13": { + "groups": [ + 3, + 18 + ], + "name": "Issue trackers", + "priority": 2 + }, + "14": { + "groups": [ + 10 + ], + "name": "Video players", + "priority": 7 + }, + "15": { + "groups": [ + 3, + 18 + ], + "name": "Comment systems", + "priority": 9 + }, + "16": { + "groups": [ + 11 + ], + "name": "Security", + "priority": 9 + }, + "17": { + "groups": [ + 9 + ], + "name": "Font scripts", + "priority": 9 + }, + "18": { + "groups": [ + 9 + ], + "name": "Web frameworks", + "priority": 7 + }, + "19": { + "groups": [ + 6 + ], + "name": "Miscellaneous", + "priority": 9 + }, + "20": { + "groups": [ + 9 + ], + "name": "Editors", + "priority": 4 + }, + "21": { + "groups": [ + 3 + ], + "name": "LMS", + "priority": 1 + }, + "22": { + "groups": [ + 7 + ], + "name": "Web servers", + "priority": 8 + }, + "23": { + "groups": [ + 7 + ], + "name": "Caching", + "priority": 7 + }, + "24": { + "groups": [ + 3 + ], + "name": "Rich text editors", + "priority": 5 + }, + "25": { + "groups": [ + 9 + ], + "name": "JavaScript graphics", + "priority": 6 + }, + "26": { + "groups": [ + 9 + ], + "name": "Mobile frameworks", + "priority": 8 + }, + "27": { + "groups": [ + 9 + ], + "name": "Programming languages", + "priority": 5 + }, + "28": { + "groups": [ + 7 + ], + "name": "Operating systems", + "priority": 6 + }, + "29": { + "groups": [ + 3 + ], + "name": "Search engines", + "priority": 4 + }, + "30": { + "groups": [ + 4 + ], + "name": "Webmail", + "priority": 2 + }, + "31": { + "groups": [ + 7 + ], + "name": "CDN", + "priority": 9 + }, + "32": { + "groups": [ + 2 + ], + "name": "Marketing automation", + "priority": 9 + }, + "33": { + "groups": [ + 7 + ], + "name": "Web server extensions", + "priority": 7 + }, + "34": { + "groups": [ + 7 + ], + "name": "Databases", + "priority": 5 + }, + "35": { + "groups": [ + 17 + ], + "name": "Maps", + "priority": 6 + }, + "36": { + "groups": [ + 2 + ], + "name": "Advertising", + "priority": 9 + }, + "37": { + "groups": [ + 7 + ], + "name": "Network devices", + "priority": 2 + }, + "38": { + "groups": [ + 10, + 7 + ], + "name": "Media servers", + "priority": 1 + }, + "39": { + "groups": [ + 4 + ], + "name": "Webcams", + "priority": 9 + }, + "41": { + "groups": [ + 1 + ], + "name": "Payment processors", + "priority": 8 + }, + "42": { + "groups": [ + 8 + ], + "name": "Tag managers", + "priority": 9 + }, + "44": { + "groups": [ + 9 + ], + "name": "CI", + "priority": 3 + }, + "45": { + "groups": [ + 7 + ], + "name": "Control systems", + "priority": 2 + }, + "46": { + "groups": [ + 4 + ], + "name": "Remote access", + "priority": 1 + }, + "47": { + "groups": [ + 9 + ], + "name": "Development", + "priority": 2 + }, + "48": { + "groups": [ + 10 + ], + "name": "Network storage", + "priority": 2 + }, + "49": { + "groups": [ + 3 + ], + "name": "Feed readers", + "priority": 1 + }, + "50": { + "groups": [ + 3 + ], + "name": "DMS", + "priority": 1 + }, + "51": { + "groups": [ + 9 + ], + "name": "Page builders", + "priority": 2 + }, + "52": { + "groups": [ + 4, + 16 + ], + "name": "Live chat", + "priority": 9 + }, + "53": { + "groups": [ + 2, + 16 + ], + "name": "CRM", + "priority": 5 + }, + "54": { + "groups": [ + 2 + ], + "name": "SEO", + "priority": 8 + }, + "55": { + "groups": [ + 16 + ], + "name": "Accounting", + "priority": 1 + }, + "56": { + "groups": [ + 5 + ], + "name": "Cryptominers", + "priority": 5 + }, + "57": { + "groups": [ + 9 + ], + "name": "Static site generator", + "priority": 1 + }, + "58": { + "groups": [ + 6 + ], + "name": "User onboarding", + "priority": 8 + }, + "59": { + "groups": [ + 9 + ], + "name": "JavaScript libraries", + "priority": 9 + }, + "60": { + "groups": [ + 7 + ], + "name": "Containers", + "priority": 8 + }, + "62": { + "groups": [ + 7 + ], + "name": "PaaS", + "priority": 8 + }, + "63": { + "groups": [ + 7 + ], + "name": "IaaS", + "priority": 8 + }, + "64": { + "groups": [ + 7 + ], + "name": "Reverse proxies", + "priority": 7 + }, + "65": { + "groups": [ + 7 + ], + "name": "Load balancers", + "priority": 7 + }, + "66": { + "groups": [ + 9 + ], + "name": "UI frameworks", + "priority": 7 + }, + "67": { + "groups": [ + 13 + ], + "name": "Cookie compliance", + "priority": 9 + }, + "68": { + "groups": [ + 9 + ], + "name": "Accessibility", + "priority": 9 + }, + "69": { + "groups": [ + 11 + ], + "name": "Authentication", + "priority": 6 + }, + "70": { + "groups": [ + 11 + ], + "name": "SSL/TLS certificate authorities", + "priority": 9 + }, + "71": { + "groups": [ + 2 + ], + "name": "Affiliate programs", + "priority": 9 + }, + "72": { + "groups": [ + 14 + ], + "name": "Appointment scheduling", + "priority": 9 + }, + "73": { + "groups": [ + 8 + ], + "name": "Surveys", + "priority": 9 + }, + "74": { + "groups": [ + 8 + ], + "name": "A/B Testing", + "priority": 9 + }, + "75": { + "groups": [ + 4, + 2 + ], + "name": "Email", + "priority": 9 + }, + "76": { + "groups": [ + 2 + ], + "name": "Personalisation", + "priority": 9 + }, + "77": { + "groups": [ + 2 + ], + "name": "Retargeting", + "priority": 9 + }, + "78": { + "groups": [ + 2 + ], + "name": "RUM", + "priority": 9 + }, + "79": { + "groups": [ + 17 + ], + "name": "Geolocation", + "priority": 9 + }, + "80": { + "groups": [ + 15 + ], + "name": "WordPress themes", + "priority": 9 + }, + "81": { + "groups": [ + 15 + ], + "name": "Shopify themes", + "priority": 9 + }, + "82": { + "groups": [ + 15 + ], + "name": "Drupal themes", + "priority": 9 + }, + "83": { + "groups": [ + 8 + ], + "name": "Browser fingerprinting", + "priority": 9 + }, + "84": { + "groups": [ + 1 + ], + "name": "Loyalty & rewards", + "priority": 9 + }, + "85": { + "groups": [ + 9 + ], + "name": "Feature management", + "priority": 9 + }, + "86": { + "groups": [ + 2 + ], + "name": "Segmentation", + "priority": 9 + }, + "87": { + "groups": [ + 15 + ], + "name": "WordPress plugins", + "priority": 9 + }, + "88": { + "groups": [ + 7 + ], + "name": "Hosting", + "priority": 9 + }, + "89": { + "groups": [ + 3 + ], + "name": "Translation", + "priority": 9 + }, + "90": { + "groups": [ + 2, + 18 + ], + "name": "Reviews", + "priority": 9 + }, + "91": { + "groups": [ + 1 + ], + "name": "Buy now pay later", + "priority": 9 + }, + "92": { + "groups": [ + 7 + ], + "name": "Performance", + "priority": 9 + }, + "93": { + "groups": [ + 14 + ], + "name": "Reservations & delivery", + "priority": 9 + }, + "94": { + "groups": [ + 2, + 1 + ], + "name": "Referral marketing", + "priority": 9 + }, + "95": { + "groups": [ + 10 + ], + "name": "Digital asset management", + "priority": 9 + }, + "96": { + "groups": [ + 2, + 18 + ], + "name": "Content curation", + "priority": 9 + }, + "97": { + "groups": [ + 2, + 8 + ], + "name": "Customer data platform", + "priority": 9 + }, + "98": { + "groups": [ + 1 + ], + "name": "Cart abandonment", + "priority": 9 + } +} \ No newline at end of file diff --git a/internal/support/Wappalyzer/groups.json b/internal/support/Wappalyzer/groups.json new file mode 100644 index 000000000..3160ecf68 --- /dev/null +++ b/internal/support/Wappalyzer/groups.json @@ -0,0 +1,53 @@ +{ + "1": { + "name": "Sales" + }, + "2": { + "name": "Marketing" + }, + "3": { + "name": "Content" + }, + "4": { + "name": "Communication" + }, + "5": { + "name": "Utilities" + }, + "6": { + "name": "Other" + }, + "7": { + "name": "Servers" + }, + "8": { + "name": "Analytics" + }, + "9": { + "name": "Web development" + }, + "10": { + "name": "Media" + }, + "11": { + "name": "Security" + }, + "13": { + "name": "Privacy" + }, + "14": { + "name": "Booking" + }, + "15": { + "name": "Add-ons" + }, + "16": { + "name": "Business tools" + }, + "17": { + "name": "Location" + }, + "18": { + "name": "User generated content" + } +} diff --git a/internal/support/Wappalyzer/package.json b/internal/support/Wappalyzer/package.json new file mode 100644 index 000000000..198bdef2e --- /dev/null +++ b/internal/support/Wappalyzer/package.json @@ -0,0 +1,35 @@ +{ + "name": "wappalyzer-core", + "description": "Identify technology on websites", + "keywords": [ + "analyze", + "identify", + "detect", + "detector", + "technology", + "cms", + "framework", + "library", + "software" + ], + "homepage": "https://www.wappalyzer.com/", + "version": "6.8.19", + "author": "Wappalyzer", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/aliasio/wappalyzer" + }, + "funding": [ + { + "url": "https://github.com/sponsors/aliasio" + }, + { + "url": "https://www.buymeacoffee.com/aliasio" + } + ], + "main": "wappalyzer.js", + "files": [ + "wappalyzer.js" + ] +} diff --git a/internal/support/Wappalyzer/script.js b/internal/support/Wappalyzer/script.js index 6db3777fd..d608d18a0 100644 --- a/internal/support/Wappalyzer/script.js +++ b/internal/support/Wappalyzer/script.js @@ -1,10 +1,11 @@ (async function() { %WAPPALYZER%; - const json = %JSON%; + const wappalyzer_technologies = %TECHNOLOGIES%; + const wappalyzer_categories = %CATEGORIES%; const cookies = %COOKIES%; const responseHeaders = %RESPONSE_HEADERS%; - Wappalyzer.setTechnologies(json.technologies); - Wappalyzer.setCategories(json.categories); + Wappalyzer.setTechnologies(wappalyzer_technologies); + Wappalyzer.setCategories(wappalyzer_categories); async function runWappalyzer() { // CSS rules @@ -37,27 +38,52 @@ {} ) - // Run the analysis - const detections = await Wappalyzer.analyze({ + // Run the analysis + const html = new window.XMLSerializer().serializeToString(document); + let detections = await Wappalyzer.analyze({ url: window.top.location.href, - html: new window.XMLSerializer().serializeToString(document), + html: html, css: css, headers: responseHeaders, meta: meta, cookies: cookies, - scripts: scripts + scriptSrc: scripts }); - const dom_detections = await analyzeDom(Wappalyzer.technologies); - const js_detections = await analyzeJS(); - const all_detections = detections.concat(dom_detections).concat(js_detections); - const detected = Wappalyzer.resolve(all_detections); + let dom = getDom(Wappalyzer.technologies); + detections = detections.concat(await analyzeDom(dom, Wappalyzer.technologies)); + detections = detections.concat(await analyzeJS(Wappalyzer.technologies)); + let resolved = Wappalyzer.resolve(detections); + + // Re-run the analysis for the subset of technologies that depend on something else + const requires = Wappalyzer.requires.filter(({ name, technologies }) => + resolved.some(({ name: _name }) => _name === name) + ) + let requires_tech = []; + for (let entry of requires) { + requires_tech = requires_tech.concat(entry['technologies']); + } + if (requires_tech.length) { + detections = detections.concat(await Wappalyzer.analyze({ + url: window.top.location.href, + html: html, + css: css, + headers: responseHeaders, + meta: meta, + cookies: cookies, + scriptSrc: scripts + }, requires_tech)); + dom = getDom(requires_tech); + detections = detections.concat(await analyzeDom(dom, requires_tech)); + detections = detections.concat(await analyzeJS(requires_tech)); + resolved = Wappalyzer.resolve(detections); + } // Parse the results into something useful let categories = {}; let apps = {}; let dedupe = {}; - for (let entry of detected) { + for (let entry of resolved) { try { if (entry) { const app = entry.name; @@ -106,42 +132,42 @@ return wptResult; } - async function analyzeJS() { + async function analyzeJS(js_technologies) { const js_tech = { - technologies: Wappalyzer.technologies + technologies: js_technologies .filter(({ js }) => Object.keys(js).length) .map(({ name, js }) => ({ name, chains: Object.keys(js) })), }; const { technologies } = js_tech; const js_data = { - js: technologies.reduce((technologies, { name, chains }) => { - chains.forEach((chain, index) => { - const value = chain - .split('.') - .reduce( - (value, method) => - value && - value instanceof Object && - Object.prototype.hasOwnProperty.call(value, method) - ? value[method] - : '__UNDEFINED__', - window - ) - - if (value !== '__UNDEFINED__') { - technologies.push({ - name, - chain, - value: - typeof value === 'string' || typeof value === 'number' - ? value - : !!value, - }) - } + js: technologies.reduce((technologies, { name, chains }) => { + chains.forEach((chain, index) => { + const value = chain + .split('.') + .reduce( + (value, method) => + value && + value instanceof Object && + Object.prototype.hasOwnProperty.call(value, method) + ? value[method] + : '__UNDEFINED__', + window + ) + + if (value !== '__UNDEFINED__') { + technologies.push({ + name, + chain, + value: + typeof value === 'string' || typeof value === 'number' + ? value + : !!value, }) - - return technologies - }, []) + } + }) + + return technologies + }, []) }; const detected = Array.prototype.concat.apply( [], @@ -149,7 +175,7 @@ js_data.js.map(async ({ name, chain, value }) => { await next() return Wappalyzer.analyzeManyToMany( - Wappalyzer.technologies.find(({ name: _name }) => name === _name), + js_technologies.find(({ name: _name }) => name === _name), 'js', { [chain]: [value] } ) @@ -159,143 +185,142 @@ return detected; } - async function analyzeDom(technologies) { - // DOM - const dom = technologies - .filter(({ dom }) => dom && dom.constructor === Object) - .map(({ name, dom }) => ({ name, dom })) - .reduce((technologies, { name, dom }) => { - const toScalar = (value) => - typeof value === 'string' || typeof value === 'number' - ? value - : !!value - - Object.keys(dom).forEach((selector) => { - let nodes = [] - - try { - nodes = document.querySelectorAll(selector) - } catch (error) { - // Ignore + function getDom(technologies) { + return technologies + .filter(({ dom }) => dom && dom.constructor === Object) + .reduce((technologies, { name, dom }) => { + const toScalar = (value) => + typeof value === 'string' || typeof value === 'number' + ? value + : !!value + + Object.keys(dom).forEach((selector) => { + let nodes = [] + + try { + nodes = document.querySelectorAll(selector) + } catch (error) { + // Continue + } + + if (!nodes.length) { + return + } + + dom[selector].forEach(({ exists, text, properties, attributes }) => { + nodes.forEach((node) => { + if (exists) { + technologies.push({ + name, + selector, + exists: '', + }) } - - if (!nodes.length) { - return + + if (text) { + const value = node.textContent.trim() + + if (value) { + technologies.push({ + name, + selector, + text: value, + }) + } } - - dom[selector].forEach(({ exists, text, properties, attributes }) => { - nodes.forEach((node) => { - if (exists) { - technologies.push({ - name, - selector, - exists: '', - }) - } - - if (text) { - const value = node.textContent.trim() - - if (value) { + + if (properties) { + Object.keys(properties).forEach((property) => { + if (Object.prototype.hasOwnProperty.call(node, property)) { + const value = node[property] + + if (typeof value !== 'undefined') { technologies.push({ name, selector, - text: value, + property, + value: toScalar(value), }) } } - - if (properties) { - Object.keys(properties).forEach((property) => { - if (Object.prototype.hasOwnProperty.call(node, property)) { - const value = node[property] - - if (typeof value !== 'undefined') { - technologies.push({ - name, - selector, - property, - value: toScalar(value), - }) - } - } - }) - } - - if (attributes) { - Object.keys(attributes).forEach((attribute) => { - if (node.hasAttribute(attribute)) { - const value = node.getAttribute(attribute) - - technologies.push({ - name, - selector, - attribute, - value: toScalar(value), - }) - } + }) + } + + if (attributes) { + Object.keys(attributes).forEach((attribute) => { + if (node.hasAttribute(attribute)) { + const value = node.getAttribute(attribute) + + technologies.push({ + name, + selector, + attribute, + value: toScalar(value), }) } }) - }) + } }) - - return technologies - }, []); - - const detected = Array.prototype.concat.apply( - [], - await Promise.all( - dom.map( - async ( - { name, selector, exists, text, property, attribute, value }, - index - ) => { - await next() - - const technology = Wappalyzer.technologies.find( - ({ name: _name }) => name === _name + }) + }) + + return technologies + }, []) + } + + async function analyzeDom(dom, technologies) { + return Array.prototype.concat.apply( + [], + await Promise.all( + dom.map( + async ({ + name, + selector, + exists, + text, + property, + attribute, + value, + }) => { + await next() + + const technology = technologies.find( + ({ name: _name }) => name === _name + ) + + if (typeof exists !== 'undefined') { + return Wappalyzer.analyzeManyToMany(technology, 'dom.exists', { + [selector]: [''], + }) + } + + if (typeof text !== 'undefined') { + return Wappalyzer.analyzeManyToMany(technology, 'dom.text', { + [selector]: [text], + }) + } + + if (typeof property !== 'undefined') { + return Wappalyzer.analyzeManyToMany(technology, `dom.properties.${property}`, { + [selector]: [value], + }) + } + + if (typeof attribute !== 'undefined') { + return Wappalyzer.analyzeManyToMany( + technology, + `dom.attributes.${attribute}`, + { + [selector]: [value], + } ) - - if (typeof exists !== 'undefined') { - return Wappalyzer.analyzeManyToMany(technology, 'dom.exists', { - [selector]: [''], - }) - } - - if (typeof text !== 'undefined') { - return Wappalyzer.analyzeManyToMany(technology, 'dom.text', { - [selector]: [text], - }) - } - - if (typeof property !== 'undefined') { - return Wappalyzer.analyzeManyToMany( - technology, - `dom.properties.${property}`, - { - [selector]: [value], - } - ) - } - - if (typeof attribute !== 'undefined') { - return Wappalyzer.analyzeManyToMany( - technology, - `dom.attributes.${attribute}`, - { - [selector]: [value], - } - ) - } - - return [] } - ) + + return [] + } ) - ); - - return detected; + ) + ) } return runWappalyzer(); diff --git a/internal/support/Wappalyzer/technologies.json b/internal/support/Wappalyzer/technologies.json deleted file mode 100644 index ca0fb11ac..000000000 --- a/internal/support/Wappalyzer/technologies.json +++ /dev/null @@ -1,27687 +0,0 @@ -{ - "$schema": "../schema.json", - "categories": { - "1": { - "name": "CMS", - "priority": 1 - }, - "2": { - "name": "Message boards", - "priority": 1 - }, - "3": { - "name": "Database managers", - "priority": 2 - }, - "4": { - "name": "Documentation", - "priority": 2 - }, - "5": { - "name": "Widgets", - "priority": 9 - }, - "6": { - "name": "Ecommerce", - "priority": 1 - }, - "7": { - "name": "Photo galleries", - "priority": 1 - }, - "8": { - "name": "Wikis", - "priority": 1 - }, - "9": { - "name": "Hosting panels", - "priority": 1 - }, - "10": { - "name": "Analytics", - "priority": 9 - }, - "11": { - "name": "Blogs", - "priority": 1 - }, - "12": { - "name": "JavaScript frameworks", - "priority": 8 - }, - "13": { - "name": "Issue trackers", - "priority": 2 - }, - "14": { - "name": "Video players", - "priority": 7 - }, - "15": { - "name": "Comment systems", - "priority": 9 - }, - "16": { - "name": "Security", - "priority": 9 - }, - "17": { - "name": "Font scripts", - "priority": 9 - }, - "18": { - "name": "Web frameworks", - "priority": 7 - }, - "19": { - "name": "Miscellaneous", - "priority": 9 - }, - "20": { - "name": "Editors", - "priority": 4 - }, - "21": { - "name": "LMS", - "priority": 1 - }, - "22": { - "name": "Web servers", - "priority": 8 - }, - "23": { - "name": "Caching", - "priority": 7 - }, - "24": { - "name": "Rich text editors", - "priority": 5 - }, - "25": { - "name": "JavaScript graphics", - "priority": 6 - }, - "26": { - "name": "Mobile frameworks", - "priority": 8 - }, - "27": { - "name": "Programming languages", - "priority": 5 - }, - "28": { - "name": "Operating systems", - "priority": 6 - }, - "29": { - "name": "Search engines", - "priority": 4 - }, - "30": { - "name": "Webmail", - "priority": 2 - }, - "31": { - "name": "CDN", - "priority": 9 - }, - "32": { - "name": "Marketing automation", - "priority": 9 - }, - "33": { - "name": "Web server extensions", - "priority": 7 - }, - "34": { - "name": "Databases", - "priority": 5 - }, - "35": { - "name": "Maps", - "priority": 6 - }, - "36": { - "name": "Advertising", - "priority": 9 - }, - "37": { - "name": "Network devices", - "priority": 2 - }, - "38": { - "name": "Media servers", - "priority": 1 - }, - "39": { - "name": "Webcams", - "priority": 9 - }, - "41": { - "name": "Payment processors", - "priority": 8 - }, - "42": { - "name": "Tag managers", - "priority": 9 - }, - "44": { - "name": "CI", - "priority": 3 - }, - "45": { - "name": "Control systems", - "priority": 2 - }, - "46": { - "name": "Remote access", - "priority": 1 - }, - "47": { - "name": "Development", - "priority": 2 - }, - "48": { - "name": "Network storage", - "priority": 2 - }, - "49": { - "name": "Feed readers", - "priority": 1 - }, - "50": { - "name": "DMS", - "priority": 1 - }, - "51": { - "name": "Page builders", - "priority": 2 - }, - "52": { - "name": "Live chat", - "priority": 9 - }, - "53": { - "name": "CRM", - "priority": 5 - }, - "54": { - "name": "SEO", - "priority": 8 - }, - "55": { - "name": "Accounting", - "priority": 1 - }, - "56": { - "name": "Cryptominers", - "priority": 5 - }, - "57": { - "name": "Static site generator", - "priority": 1 - }, - "58": { - "name": "User onboarding", - "priority": 8 - }, - "59": { - "name": "JavaScript libraries", - "priority": 9 - }, - "60": { - "name": "Containers", - "priority": 8 - }, - "62": { - "name": "PaaS", - "priority": 8 - }, - "63": { - "name": "IaaS", - "priority": 8 - }, - "64": { - "name": "Reverse proxies", - "priority": 7 - }, - "65": { - "name": "Load balancers", - "priority": 7 - }, - "66": { - "name": "UI frameworks", - "priority": 7 - }, - "67": { - "name": "Cookie compliance", - "priority": 9 - }, - "68": { - "name": "Accessibility", - "priority": 9 - }, - "69": { - "name": "Social logins", - "priority": 6 - }, - "70": { - "name": "SSL/TLS certificate authorities", - "priority": 9 - }, - "71": { - "name": "Affiliate programs", - "priority": 9 - }, - "72": { - "name": "Appointment scheduling", - "priority": 9 - }, - "73": { - "name": "Surveys", - "priority": 9 - }, - "74": { - "name": "A/B Testing", - "priority": 9 - }, - "75": { - "name": "Email", - "priority": 9 - }, - "76": { - "name": "Personalisation", - "priority": 9 - }, - "77": { - "name": "Retargeting", - "priority": 9 - }, - "78": { - "name": "RUM", - "priority": 9 - }, - "79": { - "name": "Geolocation", - "priority": 9 - }, - "80": { - "name": "WordPress themes", - "priority": 9 - }, - "81": { - "name": "Shopify themes", - "priority": 9 - }, - "82": { - "name": "Drupal themes", - "priority": 9 - }, - "83": { - "name": "Browser fingerprinting", - "priority": 9 - }, - "84": { - "name": "Loyalty & rewards", - "priority": 9 - }, - "85": { - "name": "Feature management", - "priority": 9 - }, - "86": { - "name": "Segmentation", - "priority": 9 - }, - "87": { - "name": "WordPress plugins", - "priority": 9 - }, - "88": { - "name": "Hosting", - "priority": 9 - }, - "89": { - "name": "Translation", - "priority": 9 - }, - "90": { - "name": "Reviews", - "priority": 9 - }, - "91": { - "name": "Buy now pay later", - "priority": 9 - } - }, - "technologies": { - "1C-Bitrix": { - "cats": [ - 1, - 6 - ], - "cookies": { - "BITRIX_SM_GUEST_ID": "", - "BITRIX_SM_LAST_IP": "", - "BITRIX_SM_SALE_UID": "" - }, - "description": "1C-Bitrix is a system of web project management, universal software for the creation, support and successful development of corporate websites and online stores.", - "headers": { - "Set-Cookie": "BITRIX_", - "X-Powered-CMS": "Bitrix Site Manager" - }, - "icon": "1C-Bitrix.svg", - "implies": "PHP", - "pricing": [ - "onetime", - "mid", - "recurring" - ], - "saas": true, - "scripts": "bitrix(?:\\.info/|/js/main/core)", - "website": "http://www.1c-bitrix.ru" - }, - "2B Advice": { - "cats": [ - 67 - ], - "description": "2B Advice provides a plug-in to manage GDPR cookie consent.", - "icon": "2badvice.png", - "js": { - "BBCookieControler": "" - }, - "saas": true, - "scripts": "2badvice-cdn\\.azureedge\\.net", - "website": "https://www.2b-advice.com/en/data-privacy-software/cookie-consent-plugin/" - }, - "33Across": { - "cats": [ - 36 - ], - "description": "33Across is a technology company focused on solving the challenge of consumer attention for automated advertising.", - "dom": "iframe[src*='.33across.com'], link[href*='.33across.com']", - "icon": "33Across.png", - "saas": true, - "website": "https://www.33across.com", - "xhr": "\\.33across\\.com" - }, - "3dCart": { - "cats": [ - 1, - 6 - ], - "cookies": { - "3dvisit": "" - }, - "headers": { - "X-Powered-By": "3DCART" - }, - "icon": "3dCart.png", - "scripts": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)", - "website": "http://www.3dcart.com" - }, - "4-Tell": { - "cats": [ - 76 - ], - "cookies": { - "4Tell": "", - "4TellCart": "", - "4TellSession": "" - }, - "description": "4-Tell is an ecommerce software company for retailers with AI-powered personalisation and recommendations products.", - "icon": "4-Tell.png", - "js": { - "_4TellBoost": "" - }, - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "4tellcdn\\.azureedge\\.net", - "website": "https://4-tell.com" - }, - "@sulu/web": { - "cats": [ - 59 - ], - "icon": "Sulu.svg", - "js": { - "web.startComponents": "" - }, - "website": "https://github.com/sulu/web-js" - }, - "A-Frame": { - "cats": [ - 25 - ], - "html": "]*>", - "icon": "A-Frame.svg", - "implies": "three.js", - "js": { - "AFRAME.version": "^(.+)$\\;version:\\1" - }, - "scripts": "/?([\\d.]+)?/aframe(?:\\.min)?\\.js\\;version:\\1", - "website": "https://aframe.io" - }, - "A8.net": { - "cats": [ - 71 - ], - "description": " A8.net is an affiliate marketing network.", - "dom": "img[src*='.a8.net']", - "icon": "A8.net.png", - "js": { - "A8salesCookieRepository": "", - "a8sales": "", - "map_A8": "" - }, - "scripts": "statics\\.a8\\.net", - "website": "https://www.a8.net" - }, - "AB Tasty": { - "cats": [ - 74 - ], - "description": "AB Tasty is a customer experience optimisation company. AB Tasty offers AI-driven experimentation, personalisation, and product optimisation platforms for user testing.", - "icon": "AB Tasty.svg", - "js": { - "ABTasty": "", - "_abtasty": "", - "loadABTasty": "" - }, - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "try\\.abtasty\\.com", - "website": "https://www.abtasty.com" - }, - "AD EBiS": { - "cats": [ - 36, - 32 - ], - "description": "AD EBiS is an advertising and marketing platform that offers advertisement effectiveness measurement, access and user analysis.", - "dom": "a[href*='.ebis.ne.jp/'][target='_blank']", - "icon": "ebis.png", - "js": { - "ebis.c.pageurl": "" - }, - "pricing": [ - "freemium", - "payg" - ], - "saas": true, - "scripts": "\\.ebis\\.ne\\.jp/", - "website": "http://www.ebis.ne.jp" - }, - "AMP": { - "cats": [ - 12 - ], - "description": "AMP, originally created by Google, is an open-source HTML framework developed by the AMP open-source Project. AMP is designed to help webpages load faster.", - "html": [ - "]* (?:amp|⚡)[^-]", - "]+(?:src=\"https?://mh\\d?\\.adriver\\.ru/|flashvars=\"[^\"]*(?:http:%3A//(?:ad|mh\\d?)\\.adriver\\.ru/|adriver_banner))|<(?:(?:iframe|img)[^>]+src|a[^>]+href)=\"https?://ad\\.adriver\\.ru/)", - "icon": "AdRiver.png", - "js": { - "adriver": "" - }, - "scripts": "(?:adriver\\.core\\.\\d\\.js|https?://(?:content|ad|masterh\\d)\\.adriver\\.ru/)", - "website": "http://adriver.ru" - }, - "AdRoll": { - "cats": [ - 36, - 77 - ], - "description": "AdRoll is a digital marketing technology platform that specializes in retargeting.", - "icon": "AdRoll.svg", - "js": { - "adroll_adv_id": "", - "adroll_pix_id": "" - }, - "pricing": [ - "low", - "recurring" - ], - "saas": true, - "scripts": "(?:a|s)\\.adroll\\.com", - "website": "http://adroll.com" - }, - "AdRoll CMP System": { - "cats": [ - 67 - ], - "description": "AdRoll CMP System is a consent management solution.", - "icon": "AdRoll.svg", - "js": { - "__adroll_consent": "", - "__adroll_consent_is_gdpr": "" - }, - "pricing": [ - "low", - "recurring" - ], - "saas": true, - "website": "https://www.adroll.com/features/consent-management" - }, - "AdThrive": { - "cats": [ - 36 - ], - "description": "AdThrive is an online advertising network aka ad provider for bloggers for blog monetisation.", - "icon": "AdThrive.png", - "js": { - "adthrive": "", - "adthriveVideosInjected": "" - }, - "saas": true, - "scripts": "ads\\.adthrive\\.com", - "website": "https://www.adthrive.com" - }, - "Ada": { - "cats": [ - 52 - ], - "description": "Ada is an automated customer experience company that provides chat bots used in customer support.", - "icon": "Ada.svg", - "js": { - "__AdaEmbedConstructor": "", - "adaEmbed": "" - }, - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "\\.ada\\.support", - "website": "https://www.ada.cx" - }, - "Adabra": { - "cats": [ - 32 - ], - "description": "Adabra is a SaaS omnichannel marketing automation platform to help boost sales. Adabra allows you to manage user segmentation, create workflow and campaigns through email, social, SMS and more.", - "icon": "Adabra.svg", - "js": { - "adabraPreview": "", - "adabra_version_panel": "(^.+$)\\;version:\\1", - "adabra_version_track": "(^.+$)\\;version:\\1" - }, - "pricing": [ - "poa", - "recurring" - ], - "saas": true, - "scripts": "track\\.adabra\\.com", - "website": "https://www.adabra.com", - "xhr": "my\\.adabra\\.com" - }, - "Adally": { - "cats": [ - 68 - ], - "icon": "Adally.png", - "scripts": "cloudfront\\.net/.*/adally\\.js", - "website": "https://adally.com/" - }, - "Adalyser": { - "cats": [ - 36 - ], - "description": "Adalyser is an online platform offering the tools needed to get up and running with TV advertising.", - "icon": "Adalyser.svg", - "js": { - "adalyserModules": "" - }, - "scripts": "c5\\.adalyser\\.com", - "website": "https://adalyser.com/" - }, - "Adcash": { - "cats": [ - 36 - ], - "icon": "Adcash.svg", - "js": { - "SuLoaded": "", - "SuUrl": "", - "ac_bgclick_URL": "", - "ct_nOpp": "", - "ct_nSuUrl": "", - "ct_siteunder": "", - "ct_tag": "" - }, - "scripts": "^[^\\/]*//(?:[^\\/]+\\.)?adcash\\.com/(?:script|ad)/", - "url": "^https?://(?:[^\\/]+\\.)?adcash\\.com/script/pop_", - "website": "http://adcash.com" - }, - "AddShoppers": { - "cats": [ - 5, - 10 - ], - "description": "AddShoppers is the social media marketing command center for small-medium online retailers.", - "icon": "AddShoppers.png", - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "(?:cdn\\.)?shop\\.pe/widget/", - "website": "http://www.addshoppers.com" - }, - "AddThis": { - "cats": [ - 5 - ], - "description": "AddThis is a social bookmarking service that can be integrated into a website with the use of a web widget.", - "icon": "AddThis.svg", - "js": { - "addthis": "" - }, - "scripts": "addthis\\.com/js/", - "website": "http://www.addthis.com" - }, - "AddToAny": { - "cats": [ - 5 - ], - "description": "AddToAny is a universal sharing platform that can be integrated into a website by use of a web widget or plugin.", - "icon": "AddToAny.png", - "js": { - "a2apage_init": "" - }, - "scripts": "addtoany\\.com/menu/page\\.js", - "website": "http://www.addtoany.com" - }, - "Adminer": { - "cats": [ - 3 - ], - "html": [ - "Adminer ([\\d.]+)\\;version:\\1", - "onclick=\"bodyClick\\(event\\);\" onload=\"verifyVersion\\('([\\d.]+)'\\);\">\\;version:\\1" - ], - "icon": "adminer.png", - "implies": "PHP", - "website": "http://www.adminer.org" - }, - "Admitad": { - "cats": [ - 71 - ], - "description": "Admitad is an affiliate network that acts as an intermediary between advertisers and publishers.", - "icon": "Admitad.svg", - "js": { - "ADMITAD": "", - "admitad": "" - }, - "pricing": [ - "payg" - ], - "scripts": [ - "artfut\\.com/static/(?:tracking|crossdevice)\\.min\\.js", - "cdn\\.admitad\\.com" - ], - "website": "https://www.admitad.com" - }, - "Adnegah": { - "cats": [ - 36 - ], - "headers": { - "X-Advertising-By": "adnegah\\.net" - }, - "html": "", - "" - ], - "icon": "Google Tag Manager.svg", - "js": { - "google_tag_manager": "", - "googletag": "" - }, - "saas": true, - "scripts": "googletagmanager\\.com/gtm\\.js", - "website": "http://www.google.com/tagmanager" - }, - "Google Wallet": { - "cats": [ - 41 - ], - "icon": "Google Wallet.png", - "saas": true, - "scripts": [ - "checkout\\.google\\.com", - "wallet\\.google\\.com" - ], - "website": "http://wallet.google.com" - }, - "Google Web Server": { - "cats": [ - 22 - ], - "cpe": "cpe:/a:google:web_server", - "headers": { - "Server": "gws" - }, - "icon": "Google.svg", - "website": "http://en.wikipedia.org/wiki/Google_Web_Server" - }, - "Google Web Toolkit": { - "cats": [ - 18 - ], - "cpe": "cpe:/a:google:web_toolkit", - "description": "Google Web Toolkit (GWT) is an open-source Java software development framework that makes writing AJAX applications.", - "icon": "Google Web Toolkit.png", - "implies": "Java", - "js": { - "__gwt_": "", - "__gwt_activeModules": "", - "__gwt_getMetaProperty": "", - "__gwt_isKnownPropertyValue": "", - "__gwt_stylesLoaded": "", - "__gwtlistener": "" - }, - "meta": { - "gwt:property": "" - }, - "website": "http://developers.google.com/web-toolkit" - }, - "Google Workspace": { - "cats": [ - 30, - 75 - ], - "description": "Google Workspace, formerly G Suite, is a collection of cloud computing, productivity and collaboration tools.", - "dns": { - "MX": [ - "aspmx\\.l\\.google\\.com", - "googlemail\\.com" - ] - }, - "icon": "Google Workspace.svg", - "website": "https://workspace.google.com/" - }, - "Grab Pay Later": { - "cats": [ - 41, - 91 - ], - "description": "Grab Pay Later is a Buy now pay later solution offered by Grab.", - "icon": "Grab.svg", - "saas": true, - "scripts": "grab-paylater\\.js", - "website": "https://www.grab.com/sg/finance/pay-later/" - }, - "Graffiti CMS": { - "cats": [ - 1 - ], - "cookies": { - "graffitibot": "" - }, - "icon": "Graffiti CMS.png", - "implies": "Microsoft ASP.NET", - "meta": { - "generator": "Graffiti CMS ([^\"]+)\\;version:\\1" - }, - "scripts": "/graffiti\\.js", - "website": "http://graffiticms.codeplex.com" - }, - "GrandNode": { - "cats": [ - 6 - ], - "cookies": { - "Grand.customer": "" - }, - "html": "(?:" - ], - "icon": "inspectlet.png", - "js": { - "__insp": "", - "__inspld": "" - }, - "scripts": [ - "cdn\\.inspectlet\\.com" - ], - "website": "https://www.inspectlet.com/" - }, - "Instabot": { - "cats": [ - 5, - 10, - 32, - 52, - 58 - ], - "description": "Instabot is a conversion chatbot that understands your users, and curates information, answers questions, captures contacts, and books meetings instantly.", - "icon": "Instabot.png", - "js": { - "Instabot": "" - }, - "scripts": "/rokoInstabot\\.js", - "website": "https://instabot.io/" - }, - "Instana": { - "cats": [ - 10, - 13, - 78 - ], - "description": "Instana is a Kubernetes-native APM tool which is built for new-stack including Microservices and lately Serverless but also supports the existing VM based stacks including several supported technologies.", - "icon": "Instana.svg", - "js": { - "ineum": "" - }, - "pricing": [ - "low", - "recurring" - ], - "saas": true, - "scripts": "eum\\.instana\\.io", - "website": "https://www.instana.com" - }, - "InstantCMS": { - "cats": [ - 1 - ], - "cookies": { - "InstantCMS[logdate]": "" - }, - "cpe": "cpe:/a:instantcms:instantcms", - "icon": "InstantCMS.png", - "implies": "PHP", - "meta": { - "generator": "InstantCMS" - }, - "website": "http://www.instantcms.ru" - }, - "Instapage": { - "cats": [ - 51, - 74, - 10 - ], - "description": "Instapage is a cloud-based landing page platform designed for marketing teams and agencies.", - "icon": "Instapage.svg", - "implies": [ - "Lua", - "Node.js" - ], - "js": { - "_instapageSnowplow": "", - "instapageSp": "" - }, - "pricing": [ - "mid", - "recurring" - ], - "saas": true, - "scripts": [ - "cdn\\.instapagemetrics\\.com", - "heatmap-events-collector\\.instapage\\.com" - ], - "website": "https://instapage.com" - }, - "Intel Active Management Technology": { - "cats": [ - 22, - 46 - ], - "cpe": "cpe:/a:intel:active_management_technology", - "description": "Intel Active Management Technology (AMT) is a proprietary remote management and control system for personal computers with Intel CPUs.", - "headers": { - "Server": "Intel\\(R\\) Active Management Technology(?: ([\\d.]+))?\\;version:\\1" - }, - "icon": "Intel Active Management Technology.png", - "website": "http://intel.com" - }, - "IntenseDebate": { - "cats": [ - 15 - ], - "description": "IntenseDebate is a blog commenting system that supports Typepad, Blogger and Wordpress blogs. The system allows blog owners to track and moderate comments from one place with features like threading, comment analytics, user reputation, and comment aggregation.", - "icon": "IntenseDebate.png", - "scripts": "intensedebate\\.com", - "website": "http://intensedebate.com" - }, - "Intercom": { - "cats": [ - 52, - 53 - ], - "description": "Intercom is an American software company that produces a messaging platform which allows businesses to communicate with prospective and existing customers within their app, on their website, through social media, or via email.", - "icon": "Intercom.svg", - "js": { - "Intercom": "" - }, - "pricing": [ - "mid", - "recurring" - ], - "saas": true, - "scripts": "(?:api\\.intercom\\.io/api|static\\.intercomcdn\\.com/intercom\\.v1)", - "website": "https://www.intercom.com" - }, - "Intercom Articles": { - "cats": [ - 4 - ], - "description": "Intercom Articles is a tool to create, organise and publish help articles.", - "html": "]+>We run on Intercom", - "icon": "Intercom.svg", - "website": "https://www.intercom.com/articles" - }, - "Intershop": { - "cats": [ - 6 - ], - "html": "(?:CDS )?Invenio\\s*v?([\\d\\.]+)?\\;version:\\1", - "icon": "Invenio.png", - "website": "http://invenio-software.org" - }, - "Inveon": { - "cats": [ - 6 - ], - "cookies": { - "INV.Customer": "\\;confidence:50", - "inveonSessionId": "" - }, - "description": "Inveon is a technology company that has been delivering ecommerce infrastructure software and mcommerce applications.", - "icon": "Inveon.svg", - "js": { - "InvApp": "\\;confidence:50", - "invTagManagerParams": "" - }, - "scripts": "Scripts/_app/Inv(?:\\w+)\\.js\\?v=(.+)$\\;version:\\1", - "website": "https://www.inveon.com" - }, - "Ionic": { - "cats": [ - 18 - ], - "icon": "ionic.png", - "js": { - "Ionic.config": "", - "Ionic.version": "^(.+)$\\;version:\\1" - }, - "website": "https://ionicframework.com" - }, - "Ionicons": { - "cats": [ - 17 - ], - "description": "Ionicons is an open-source icon set crafted for web, iOS, Android, and desktop apps.", - "html": "]* href=[^>]+ionicons(?:\\.min)?\\.css", - "icon": "Ionicons.png", - "website": "http://ionicons.com" - }, - "Irroba": { - "cats": [ - 6 - ], - "html": "]*href=\"https://www\\.irroba\\.com\\.br", - "icon": "irroba.svg", - "website": "https://www.irroba.com.br/" - }, - "Isotope": { - "cats": [ - 59 - ], - "description": "Isotope.js is a JavaScript library that makes it easy to sort, filter, and add Masonry layouts to items on a webpage.", - "icon": "Isotope.svg", - "js": { - "Isotope": "", - "init_isotope": "" - }, - "oss": true, - "pricing": [ - "low", - "freemium", - "onetime" - ], - "website": "https://isotope.metafizzy.co" - }, - "Izooto": { - "cats": [ - 32, - 5 - ], - "description": "iZooto is a user engagement and retention tool that leverages web push notifications to help business to drive repeat traffic, leads and sales.", - "icon": "Izooto.png", - "js": { - "Izooto": "", - "_izooto": "" - }, - "pricing": [ - "mid", - "recurring" - ], - "saas": true, - "scripts": "cdn\\.izooto\\.\\w+", - "website": "https://www.izooto.com" - }, - "J2Store": { - "cats": [ - 6 - ], - "description": "J2Store is a Joomla shopping cart and ecommerce extension.", - "icon": "j2store.png", - "js": { - "j2storeURL": "" - }, - "requires": "Joomla", - "website": "https://www.j2store.org/" - }, - "JANet": { - "cats": [ - 71 - ], - "description": "JANet is an affiliate marketing network.", - "dom": "img[src*='.j-a-net.jp'],img[data-src*='.j-a-net.jp']", - "icon": "JANet.png", - "website": "https://j-a-net.jp" - }, - "JAlbum": { - "cats": [ - 7 - ], - "description": "jAlbum is across-platform photo website software for creating and uploading galleries from images and videos.", - "icon": "JAlbum.png", - "implies": "Java", - "meta": { - "generator": "JAlbum( [\\d.]+)?\\;version:\\1" - }, - "website": "http://jalbum.net/en" - }, - "JBoss Application Server": { - "cats": [ - 22 - ], - "headers": { - "X-Powered-By": "JBoss(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Application Server.png", - "website": "http://jboss.org/jbossas.html" - }, - "JBoss Web": { - "cats": [ - 22 - ], - "excludes": "Apache Tomcat", - "headers": { - "X-Powered-By": "JBossWeb(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Web.png", - "implies": "JBoss Application Server", - "website": "http://jboss.org/jbossweb" - }, - "JET Enterprise": { - "cats": [ - 6 - ], - "headers": { - "powered": "jet-enterprise" - }, - "icon": "JET Enterprise.svg", - "website": "http://www.jetecommerce.com.br/" - }, - "JS Charts": { - "cats": [ - 25 - ], - "icon": "JS Charts.png", - "js": { - "JSChart": "" - }, - "scripts": "jscharts.{0,32}\\.js", - "website": "http://www.jscharts.com" - }, - "JSEcoin": { - "cats": [ - 56 - ], - "description": "JSEcoin is a way to mine, receive payments for your goods or services and transfer cryptocurrency", - "icon": "JSEcoin.png", - "js": { - "jseMine": "" - }, - "scripts": "^(?:https):?//load\\.jsecoin\\.com/load/", - "website": "https://jsecoin.com/" - }, - "JShop": { - "cats": [ - 6 - ], - "description": "JShop is the ecommerce database solution marketed by Whorl Ltd. worldwide.", - "icon": "JShop.svg", - "js": { - "jss_1stepDeliveryType": "", - "jss_1stepFillShipping": "" - }, - "website": "http://www.whorl.co.uk" - }, - "JTL Shop": { - "cats": [ - 6 - ], - "cookies": { - "JTLSHOP": "" - }, - "description": "JTL Shop is an ecommerce product created by JTL Software company.", - "html": "(?:]+name=\"JTLSHOP|", - "icon": "Java.png", - "website": "https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html" - }, - "Jekyll": { - "cats": [ - 57 - ], - "cpe": "cpe:/a:jekyllrb:jekyll", - "description": "Jekyll is a blog-aware, static site generator for personal, project, or organisation sites.", - "html": [ - "Powered by ]*>JekyllJenkins ver\\. ([\\d.]+)\\;version:\\1", - "icon": "Jenkins.png", - "implies": "Java", - "js": { - "jenkinsCIGlobal": "", - "jenkinsRules": "" - }, - "website": "https://jenkins.io/" - }, - "Jetshop": { - "cats": [ - 6 - ], - "html": "<(?:div|aside) id=\"jetshop-branding\">", - "icon": "Jetshop.png", - "js": { - "JetshopData": "" - }, - "website": "http://jetshop.se" - }, - "Jetty": { - "cats": [ - 22 - ], - "headers": { - "Server": "Jetty(?:\\(([\\d\\.]*\\d+))?\\;version:\\1" - }, - "icon": "Jetty.png", - "implies": "Java", - "website": "http://www.eclipse.org/jetty" - }, - "Jibres": { - "cats": [ - 6, - 55 - ], - "cookies": { - "jibres": "" - }, - "description": "Jibres is an ecommerce solution with an online store builder and Point-of-Sale (PoS) software.", - "headers": { - "X-Powered-By": "Jibres" - }, - "icon": "Jibres.svg", - "js": { - "jibres": "" - }, - "meta": { - "generator": "Jibres" - }, - "scripts": "/jibres\\.js", - "website": "https://jibres.com" - }, - "Jimdo": { - "cats": [ - 1 - ], - "description": "Jimdo is a website-builder and all-in-one hosting solution, designed to enable users to build their own websites.", - "headers": { - "X-Jimdo-Instance": "", - "X-Jimdo-Wid": "" - }, - "icon": "jimdo.png", - "pricing": [ - "low", - "freemium" - ], - "saas": true, - "url": "\\.jimdo\\.com/", - "website": "https://www.jimdo.com" - }, - "Jirafe": { - "cats": [ - 10, - 32 - ], - "icon": "Jirafe.png", - "js": { - "jirafe": "" - }, - "scripts": "/jirafe\\.js", - "website": "https://docs.jirafe.com" - }, - "Jitsi": { - "cats": [ - 52 - ], - "description": "Jitsi is a free and open-source multiplatform voice (VoIP), videoconferencing and instant messaging applications for the web platform.", - "icon": "Jitsi.png", - "scripts": "lib-jitsi-meet.*\\.js", - "website": "https://jitsi.org" - }, - "Jive": { - "cats": [ - 19 - ], - "headers": { - "X-JIVE-USER-ID": "", - "X-JSL": "", - "X-Jive-Flow-Id": "", - "X-Jive-Request-Id": "", - "x-jive-chrome-wrapped": "" - }, - "icon": "Jive.png", - "website": "http://www.jivesoftware.com" - }, - "JivoChat": { - "cats": [ - 52 - ], - "description": "JivoChat is a live chat solution for websites offering customizable web and mobile chat widgets.", - "icon": "JivoChat.png", - "js": { - "jivo_api": "", - "jivo_version": "([\\d.]+)\\;version:\\1" - }, - "pricing": [ - "freemium", - "recurring", - "payg" - ], - "saas": true, - "scripts": "\\.jivosite\\.com", - "website": "https://www.jivosite.com" - }, - "JobberBase": { - "cats": [ - 19 - ], - "icon": "JobberBase.png", - "implies": "PHP", - "js": { - "Jobber": "" - }, - "meta": { - "generator": "Jobberbase" - }, - "website": "http://www.jobberbase.com" - }, - "JoomShopping": { - "cats": [ - 6 - ], - "description": "JoomShopping is an open-source ecommerce plugin for Joomla.", - "icon": "JoomShopping.png", - "implies": "Joomla", - "js": { - "joomshoppingVideoHtml5": "" - }, - "oss": true, - "pricing": [ - "freemium", - "onetime" - ], - "scripts": "/components/com_jshopping/", - "website": "https://www.webdesigner-profi.de/joomla-webdesign/joomla-shop" - }, - "Joomla": { - "cats": [ - 1 - ], - "cpe": "cpe:/a:joomla:joomla", - "description": "Joomla is a free and open-source content management system for publishing web content.", - "headers": { - "X-Content-Encoded-By": "Joomla! ([\\d.]+)\\;version:\\1" - }, - "html": "(?:]+id=\"wrapper_r\"|<(?:link|script)[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", - "icon": "Joomla.svg", - "implies": "PHP", - "js": { - "Joomla": "", - "jcomments": "" - }, - "meta": { - "generator": "Joomla!(?: ([\\d.]+))?\\;version:\\1" - }, - "oss": true, - "url": "option=com_", - "website": "https://www.joomla.org" - }, - "Judge.me": { - "cats": [ - 90 - ], - "description": "Judge.me powers product reviews on ecommerce stores.", - "icon": "Judge.svg", - "js": { - "judgeme": "" - }, - "pricing": [ - "low", - "recurring" - ], - "saas": true, - "scripts": "cdn\\.judge\\.me", - "website": "https://judge.me/" - }, - "Jumpseller": { - "cats": [ - 6 - ], - "description": "Jumpseller is a cloud ecommerce solution for small businesses.", - "icon": "Jumpseller.svg", - "js": { - "Jumpseller": "" - }, - "pricing": [ - "low", - "recurring" - ], - "saas": true, - "scripts": [ - "assets\\.jumpseller\\.\\w+/", - "jumpseller-apps\\.herokuapp\\.\\w+/" - ], - "website": "https://jumpseller.com" - }, - "Justo": { - "cats": [ - 6 - ], - "description": "Justo is a subscription-based software that allows anyone to set up an online store and sell their products with delivery options.", - "icon": "Justo.svg", - "scripts": "\\.getjusto\\.com/", - "saas": true, - "pricing": [ - "high", - "recurring" - ], - "website": "https://www.getjusto.com" - }, - "K2": { - "cats": [ - 19 - ], - "html": "", - "icon": "Lightspeed.svg", - "pricing": [ - "low" - ], - "saas": true, - "scripts": "http://assets\\.webshopapp\\.com", - "url": "seoshop.webshopapp.com", - "website": "http://www.lightspeedhq.com/products/ecommerce/" - }, - "LinkSmart": { - "cats": [ - 36 - ], - "icon": "LinkSmart.png", - "js": { - "LS_JSON": "", - "LinkSmart": "", - "_mb_site_guid": "" - }, - "scripts": "^https?://cdn\\.linksmart\\.com/linksmart_([\\d.]+?)(?:\\.min)?\\.js\\;version:\\1", - "website": "http://linksmart.com" - }, - "Linkedin Insight Tag": { - "cats": [ - 10 - ], - "dom": "noscript > img[src*='dc.ads.linkedin.com']", - "icon": "Linkedin.svg", - "js": { - "_linkedin_data_partner_id": "" - }, - "scripts": "snap\\.licdn\\.com/li\\.lms-analytics/insight\\.min\\.js", - "website": "https://business.linkedin.com/marketing-solutions/insight-tag" - }, - "Linkedin Sign-in": { - "cats": [ - 69 - ], - "description": "Linkedin Sign-In is an authentication system that reduces the burden of login for users, by enabling them to sign in with their Linkedin account.", - "icon": "Linkedin.svg", - "js": { - "OnLinkedInAuth": "", - "onLinkedInLoad": "" - }, - "scripts": "platform\\.linkedin\\.com/(?:.*)?in\\.js(?:\\?version)?([\\d.]+)?\\;version:\\1", - "website": "https://www.linkedin.com/developers" - }, - "Liquid Web": { - "cats": [ - 62 - ], - "headers": { - "x-lw-cache": "" - }, - "icon": "liquidweb.svg", - "website": "https://www.liquidweb.com" - }, - "List.js": { - "cats": [ - 59 - ], - "icon": "List.js.png", - "js": { - "List": "\\;confidence:50" - }, - "scripts": [ - "list\\.js/\\;confidence:50", - "@([\\d.]+)/(?:/dist)?list\\.(?:min\\.)?js\\;version:\\1" - ], - "website": "http://listjs.com" - }, - "Listrak": { - "cats": [ - 32 - ], - "description": "Listrak is a AI-based marketing automation and CRM solutions that unify, interpret and personalise data to engage customer across channels and devices.", - "icon": "Listrak.png", - "js": { - "_LTKSignup": "", - "_LTKSubscriber": "" - }, - "pricing": [ - "poa" - ], - "saas": true, - "scripts": [ - "(?:cdn|s1)\\.listrakbi\\.com", - "services\\.listrak\\.com" - ], - "website": "https://www.listrak.com" - }, - "LiteSpeed": { - "cats": [ - 22 - ], - "cpe": "cpe:/a:litespeedtech:litespeed_web_server", - "description": "LiteSpeed is a high-scalability web server.", - "headers": { - "Server": "^LiteSpeed$" - }, - "icon": "LiteSpeed.svg", - "website": "http://litespeedtech.com" - }, - "Litespeed Cache": { - "cats": [ - 23, - 87 - ], - "description": "LiteSpeed Cache is an all-in-one site acceleration plugin for WordPress.", - "headers": { - "x-litespeed-cache": "" - }, - "icon": "litespeed-cache.png", - "requires": "LiteSpeed", - "website": "https://wordpress.org/plugins/litespeed-cache/" - }, - "Lithium": { - "cats": [ - 1 - ], - "cookies": { - "LithiumVisitor": "" - }, - "html": " ]+Powered by Lithium", - "icon": "Lithium.png", - "implies": "PHP", - "js": { - "LITHIUM": "" - }, - "website": "https://www.lithium.com" - }, - "Live Story": { - "cats": [ - 1 - ], - "icon": "LiveStory.png", - "js": { - "LSHelpers": "", - "LiveStory": "" - }, - "website": "https://www.livestory.nyc/" - }, - "LiveAgent": { - "cats": [ - 52 - ], - "description": "LiveAgent is an online live chat platform. The software provides a ticket management system.", - "icon": "LiveAgent.png", - "js": { - "LiveAgent": "" - }, - "pricing": [ - "payg" - ], - "saas": true, - "website": "https://www.liveagent.com" - }, - "LiveChat": { - "cats": [ - 52 - ], - "description": "LiveChat is an online customer service software with online chat, help desk software, and web analytics capabilities.", - "icon": "LiveChat.png", - "pricing": [ - "payg" - ], - "saas": true, - "scripts": "cdn\\.livechatinc\\.com/.*tracking\\.js", - "website": "http://livechatinc.com" - }, - "LiveHelp": { - "cats": [ - 52, - 53 - ], - "description": "LiveHelp is an online chat tool.", - "icon": "LiveHelp.png", - "js": { - "LHready": "" - }, - "pricing": [ - "low" - ], - "saas": true, - "website": "http://www.livehelp.it" - }, - "LiveIntent": { - "cats": [ - 75, - 36 - ], - "description": "LiveIntent is an email ad monetization platform.", - "icon": "LiveIntent.svg", - "js": { - "LI.advertiserId": "\\d+" - }, - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "\\.liadm\\.com", - "website": "https://www.liveintent.com", - "xhr": "\\.liadm\\.com" - }, - "LiveJournal": { - "cats": [ - 11 - ], - "description": "LiveJournal is a social networking service where users can keep a blog, journal or diary.", - "icon": "LiveJournal.png", - "url": "\\.livejournal\\.com", - "website": "http://www.livejournal.com" - }, - "LivePerson": { - "cats": [ - 52 - ], - "description": "LivePerson is a tool for conversational chatbots and messaging.", - "icon": "LivePerson.png", - "pricing": [ - "poa" - ], - "saas": true, - "scripts": "^https?://lptag\\.liveperson\\.net/tag/tag\\.js", - "website": "https://www.liveperson.com/" - }, - "LiveRamp PCM": { - "cats": [ - 67 - ], - "description": "LiveRamp PCM is a preference and consent management platform that enables comply with the ePrivacy Directive, GDPR, CCPA, and other data protection and privacy laws and regulations.", - "dom": "iframe[src*='gdpr-consent-tool\\.privacymanager\\.io']", - "icon": "LiveRamp.svg", - "js": { - "wpJsonpLiverampGdprCmp": "" - }, - "scripts": "gdpr\\.privacymanager\\.io", - "website": "https://liveramp.com/our-platform/preference-consent-management" - }, - "LiveStreet CMS": { - "cats": [ - 1 - ], - "headers": { - "X-Powered-By": "LiveStreet CMS" - }, - "icon": "LiveStreet CMS.png", - "implies": "PHP", - "js": { - "LIVESTREET_SECURITY_KEY": "" - }, - "website": "http://livestreetcms.com" - }, - "LiveZilla": { - "cats": [ - 52 - ], - "description": "LiveZilla is a web-based live support platform.", - "dom": "#lz_overlay_chat", - "icon": "LiveZilla.png", - "js": { - "lz_chat_execute": "", - "lz_code_id": "(?:[\\w\\d]+)", - "lz_tracking_set_widget_visibility": "" - }, - "pricing": [ - "onetime", - "mid" - ], - "saas": false, - "website": "https://www.livezilla.net" - }, - "Livefyre": { - "cats": [ - 15 - ], - "description": "Livefyre is a platform that integrates with the social web to boost social interaction.", - "html": "<[^>]+(?:id|class)=\"livefyre", - "icon": "Livefyre.png", - "js": { - "FyreLoader": "", - "L.version": "^(.+)$\\;confidence:0\\;version:\\1", - "LF.CommentCount": "", - "fyre": "" - }, - "scripts": "livefyre_init\\.js", - "website": "http://livefyre.com" - }, - "Liveinternet": { - "cats": [ - 10 - ], - "html": [ - "