Security Alert: Malware Risk Confirmed
WPSNIFFER
ID: kihhefcbenhkjgjhchanjfhhflaojldn
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- andyforsberg.comView Profile
- Privacy
- Privacy Policy
- Help
- Help Center
- Website
- Visit
Detects the WordPress theme, plugins, version, and host used on any WordPress site.
Detects active WordPress theme being used on current WordPress website and links to the theme, if not found then returns a Google search for "{theme's name} wordpress theme".
The extension initializes Parse.com (a third-party BaaS) with hardcoded API credentials and accumulates the domain of every WordPress site the user visits in local storage, then batch-uploads the full list to Parse.com every 10 minutes via DataAccess.flush(). The uploaded payload contains the stripped domain (browsing history) of visited sites. This data flows to a third-party server unrelated to the publisher domain (andyforsberg.com), is never disclosed in the CWS listing, and the TODO comment on line 8 confirms the developer knew it was not production-ready but shipped it anyway.
var WPSNIFFER_RESULTS = "WPSNIFFER_RESULTS";var APP_ID = "L1AlvBHhdJr2L79q7h382XT5hiWoZMo9czWfOqI3";var APP_KEY = "vKHvkIHXtMDhZJlkzr4cHPnhOCuy4pEIHueLXf9n";Parse.initialize(APP_ID, APP_KEY);var ThemeResult = Parse.Object.extend("TestObject"); // TODO change in productionfunction DataAccess() {};DataAccess.prototype.add = function(result) { var self = this; if (!result || !result.domain || !result.theme) { return; } try { result.theme = result.theme.split("-")[0]; result.domain = result.domain.replace(/http[s]?:\/\//, '');The flush() method retrieves the accumulated list of visited WordPress domains from local storage and uploads them all to Parse.com via Parse.Object.saveAll(). This is called on extension startup and then on a 10-minute interval (background.js line 109). The 'TODO remove in production' comment on line 60 is further evidence that the developer deliberately left data-exfiltration code active in a published extension, not by accident.
DataAccess.prototype.flush = function() { var self = this; try { chrome.storage.local.get({ WPSNIFFER_RESULTS: [] }, function(o) { if (chrome.runtime.lastError) { return; } var results = o[WPSNIFFER_RESULTS] || []; if (results.length) { var collection = results.map(function(result) { result.name = result.domain; // TODO remove in production return new ThemeResult(result); }); Parse.Object.saveAll(collection, { success: function() { chrome.storage.local.set({ WPSNIFFER_RESULTS: [] }, function() {}); }, error: function() {} }); } }); } catch (ex) {}};The background page starts an exfiltration loop immediately on load and repeats every 10 minutes. The comment 'start upload to parse.com loop' is explicit about the intent. Combined with the domain collection in data.js, this creates a persistent covert telemetry channel that operates entirely in the background without user awareness or consent.
var UPLOAD_INTERVAL = 10 * 60 * 1000; // 10 minutes...// start upload to parse.com loopdataAccess.flush();setInterval(function() { dataAccess.flush();}, UPLOAD_INTERVAL);By severity
Versions scanned
Showing 1 of 2 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 2.23 | 3 |
Files with findings
2 distinct paths — top paths by unique finding count:
- data.js2
- background.js1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.