SearchLock Tab

ID: ohdphinnjkbfgimbcpdjdigbbkmngcge

Could be malicious

Supported Languages

🇺🇸English

Extension Info & Metadata

Status
Removed
Version
1.0.2
Size
0.27 MB
Rating
4.2/5
Reviews
87
Users
10,000
Type
Extension
Updated
Dec 10, 2022
Category
Productivity Tools
Price
Free
Featured
Yes
Visibility
Listed
Mature
No
By Google
No
Trusted
Yes

Publisher Contextual Analysis

Trusted
Author
https://searchlock.comView Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
Yes
Mailbox exists
Yes
Website
Visit
Total Extensions
3
Active
0
Obsolete
3
Listed
3
Unlisted
0
Total Users
115,956

Privacy-enhancing search engine new tab page.

Search the web without being tracked from your new tab page! SearchLock Tab adds a privacy-friendly SearchLock search box to your browser's new tab page. When you use SearchLock, you can rest easy knowing that: • We don't track you in or out of private mode. • We don’t ask for or store your personal information. • We don't associate your searches with your personal information since we never ask for it in the first place. • We don't follow you with ads. -------------------- Extension Features: -------------------- - Updates your Chrome new tab page to show a privacy-friendly search box from SearchLock. - Use your SearchLock Tab page to search the web privately, without being tracked or profiled for advertising. Privacy policy: https://www.searchlock.com/pages/privacy Thanks for using SearchLock Tab! Get in touch with us any time at https://www.searchlock.com/support Adding this extension to Chrome sets your new tab page to SearchLock Tab.

Item
Type
Severity
Description
declarativeNetRequestWithHostAccess
Permission
Critical
This permission combines network request modification with host permissions. Rated Critical because it can modify requests for specific domains, potentially targeting sensitive websites with precise attack rules.
topSites
Permission
High
This permission accesses the list of most visited websites. Rated High because it can reveal browsing patterns, identify frequently accessed service, and gather user behavior data.
storage
Permission
Medium
This permission allows storing data locally in the browser. Rated Medium because it can persist sensitive user data, track user activities over time, and potentially store malicious payloads.
tabs
Permission
Medium
This permission enables tab management and monitoring. Rated Medium because it can track open tabs, access tab metadata, and monitor user browsing patterns.
*://*.searchlock.com/*
Host
Medium
Host permission — access limited to this URL pattern.
alarms
Permission
Low
This permission schedules periodic tasks. Rated Low because it can only trigger events at specified times without access to sensitive data.

The extension fetches a remote configuration (`dynamic_redirect_params`) from the developer's server on every startup and every 12 hours (720-minute alarm). These server-controlled parameters are then used to dynamically modify URL query strings on all searchlock.com search requests via declarativeNetRequest rules. This is a remote code/config injection vector — the server can silently change what tracking or affiliate parameters get appended to every search query without an extension update.

js/background.js (Line 31)
async function getRemoteConfig() {  try {    const query = new URLSearchParams({      aid: appId,      a: alias,      ua: limitedUA,      version: `${version}_chrome`,    });    const getUrl = `${baseUrl}/api/safelist/?${query.toString()}`;    const response = await fetch(getUrl);    const responseObj = await response.json();    dynamicRedirectParams = responseObj.dynamic_redirect_params;    setOtherRedirectParams();    chrome.storage.sync.set({      dynamic_redirect_params: dynamicRedirectParams,    });  } catch (error) {    console.log("Could not parse Safelist.");    console.log(error);    logError("Safelist parse error: " + error.message);  }}

A hidden iframe is silently injected into every page on *.searchlock.com, pinging a remote attribution endpoint with a persistent unique user alias, extension ID, and version. The iframe has display:none to avoid any visible indication to the user. This constitutes covert tracking of the user's browsing sessions across all pages on the domain.

js/contentScripts.js (Line 7)
function injectAttribution() {  if (alias) {    const query = new URLSearchParams({      alias,      aid: appId,      v: version,      extId,    });    const attributionUrl = `${baseUrl}/pages/attribution?${query.toString()}`;    const iframe = document.createElement("iframe");    iframe.src = attributionUrl;    iframe.id = "cnvrt";    iframe.style.display = "none";    const injectInterval = setInterval(function() {      // make sure document.body is already available before injecting the iframe      if (document.body) {        clearInterval(injectInterval);        document.body.appendChild(iframe);      }    }, 50);  }}

The ident() function injects a hidden DOM element into every searchlock.com page containing the user's persistent alias (GUID), install date offset (days since install), extension ID and version — encoded as data attributes readable by any JavaScript running on the page. This exfiltrates the unique user identifier and usage duration to the host page's own scripts without explicit user consent.

js/contentScripts.js (Line 69)
chrome.storage.sync.get(["install_attributed", "alias"], function(data) {if (data.install_attributed) return;alias = data.alias;injectAttribution();});})();// When at searchlock.com, pass install date and source as an invisible divfunction ident() {  chrome.storage.sync.get(["alias", "install_date"], function(data) {    if (data.alias) {      let snc = 0;      if (data.install_date) {        const jdt = data.install_date.split("-");        const sdt = new Date(jdt[0], jdt[1] - 1, jdt[2]);        const edt = new Date();        snc = Math.abs(Math.round((edt - sdt) / 86400000));      }      const data_params = {        ext_aid: appId,        ext_alias: data.alias,        ext_id: chrome.runtime.id,        ext_ver: chrome.runtime.getManifest().version,      };      const div = document.createElement("div");      div.style.display = "none";      div.setAttribute("id", "sl_user");      div.setAttribute("class", "sl_app");      div.setAttribute("data-guid", data.alias);      div.setAttribute("data-dsi", snc);      div.setAttribute("data-v", chrome.runtime.getManifest().version);      div.setAttribute("data-extid", chrome.runtime.id);      div.setAttribute("data-params", JSON.stringify(data_params));      document.body.appendChild(div);    }  });}

Dynamic declarativeNetRequest rules are installed at runtime using parameters fetched from a remote server, silently appending or replacing query parameters on every search request to searchlock.com. Because the parameter set is server-controlled and refreshed periodically, the operator can add arbitrary tracking or affiliate identifiers to user searches without any user visibility or further extension update review.

js/background.js (Line 220)
function updateDynamicRules() {  chrome.declarativeNetRequest.updateDynamicRules({    addRules: [{      id: 1,      action: {        type: "redirect",        redirect: {          transform: {            queryTransform: {              addOrReplaceParams: Array.from(                  new URLSearchParams(otherRedirectParams)                  .entries()                )                .map(([key, value]) => ({                  key,                  value                })),            },          },        },      },      condition: {        regexFilter: "searchlock.com/search/.*",        resourceTypes: ["main_frame"],      },    }, ],    removeRuleIds: [1],  });}

The content script listens for window.postMessage events from any subdomain of searchlock.com and, upon receipt, stores arbitrary `pbParams` objects from the remote page into chrome.storage.sync and forwards them to the background service worker to modify all future search redirect parameters. The origin check uses a regex (`.+\.searchlock\.com`) that could match attacker-controlled subdomains, and the pbParams payload is trusted and stored/applied without further validation — any searchlock.com subdomain can control what parameters get injected into the user's search queries.

js/contentScripts.js (Line 30)
window.addEventListener(  "message",  function(event) {    const slPattern = /.+\.searchlock\.com/i;    if (slPattern.test(event.origin)) {      if (        event.data.message === "sl_install_attributed" &&        event.data.extId === extId      ) {        chrome.storage.sync.set({          install_attributed: true        }, function() {          console.debug("Install attributed");        });        const postbackParams = event.data.pbParams;        if (          typeof postbackParams === "object" &&          Object.keys(postbackParams).length > 0        ) {          chrome.storage.sync.set({            pb_params: postbackParams          }, function() {            console.debug(postbackParams);            chrome.runtime.sendMessage({              command: "set_redirect_params",              pb_params: postbackParams,            });          });        }      }    }  },  false);

Internal error messages are silently transmitted to the developer's server along with the OS, browser type, and app ID. While error logging itself is common, the unconditional exfiltration of error message strings (which could contain URL fragments or user query data from stack traces) to a remote endpoint without user consent or disclosure is a privacy concern.

js/background.js (Line 260)
function logError(message) {  const params = new URLSearchParams({    message,    aid: appId,    os,    version,  });  fetch(`${baseUrl}/api/extlog/error/${browser}?${params.toString()}`);}

The extension reads the user's top browsing sites via chrome.topSites and persists them to chrome.storage.sync (which syncs across all of the user's Chrome profiles). The full topSites list is also returned to the new tab page content script for use in the autocomplete feature, making the user's browsing history available to page-level JavaScript. Storing browsing history in sync storage means it is uploaded to Google and tied to the user's Google account.

js/background.js (Line 112)
function getHistory(sendResponse) {  chrome.topSites.get((topsitesResponse) => {    var sites = [];    var slicedTopSites;    chrome.storage.sync.get(["saved_favorites"], ({      saved_favorites    }) => {      if (!saved_favorites) {        topsitesResponse.forEach(function(key, value) {          sites.push({            url: value.url,            title: value.title          });        });        slicedTopSites = sites.slice(0, 9);        chrome.storage.sync.set({            saved_favorites: slicedTopSites          },          function() {}        );      }      sendResponse({        results: topsitesResponse      });    });  });}

By severity

Critical1
High4
Medium2
Low0

Versions scanned

Showing 1 of 1 scanned version with more than one unique finding. Counts are unique findings that include each version.

Extension VersionCode Review Findings
1.0.27

Files with findings

2 distinct paths — top paths by unique finding count:

  • js/background.js4
  • js/contentScripts.js3
S.No.
Category
Severity
File
Summary
Found in Version
1Remote Code Loading
critical
js/background.js (line 31)The extension fetches a remote configuration (`dynamic_redirect_params`) from the developer's server on every startup and every 12 hours (720-minute alarm). These server-controlled parameters are then used to dynamica…
2Network Interception
high
js/background.js (line 220)Dynamic declarativeNetRequest rules are installed at runtime using parameters fetched from a remote server, silently appending or replacing query parameters on every search request to searchlock.com. Because the param…
3Privilege Escalation
high
js/contentScripts.js (line 30)The content script listens for window.postMessage events from any subdomain of searchlock.com and, upon receipt, stores arbitrary `pbParams` objects from the remote page into chrome.storage.sync and forwards them to t…
4Tracking
high
js/contentScripts.js (line 7)A hidden iframe is silently injected into every page on *.searchlock.com, pinging a remote attribution endpoint with a persistent unique user alias, extension ID, and version. The iframe has display:none to avoid any …
5Unauthorized Data Collection
high
js/contentScripts.js (line 69)The ident() function injects a hidden DOM element into every searchlock.com page containing the user's persistent alias (GUID), install date offset (days since install), extension ID and version — encoded as data attr…
6Data Exfiltration
medium
js/background.js (line 260)Internal error messages are silently transmitted to the developer's server along with the OS, browser type, and app ID. While error logging itself is common, the unconditional exfiltration of error message strings (wh…
7Unauthorized Data Collection
medium
js/background.js (line 112)The extension reads the user's top browsing sites via chrome.topSites and persists them to chrome.storage.sync (which syncs across all of the user's Chrome profiles). The full topSites list is also returned to the new…
URLs
25
IPv4
0
IPv6
0

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.

www.${domain}`-https://www.${domain}`
dev.${domain}`;-https://dev.${domain}`;
www.searchlock.com-https://www.searchlock.com
www.searchlock.com/abouthttps://www.searchlock.com/about
www.searchlock.com/supporthttps://www.searchlock.com/support
results.searchlock.com/search/https://results.searchlock.com/search/
www.searchlock.com/pages/eulahttps://www.searchlock.com/pages/eula
www.searchlock.com/pages/privacyhttps://www.searchlock.com/pages/privacy
www.w3.org/1999/02/22-rdf-syntax-nshttp://www.w3.org/1999/02/22-rdf-syntax-ns#
ns.adobe.com/xap/1.0/mm/http://ns.adobe.com/xap/1.0/mm/
Showing 1 to 10 of 30 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

No IP addresses found
Version
Size
Is Malicious
Findings
Permhash
1.0.2
Latest
0.27 MB
Malicious
7
Showing 1 to 1 of 10 rows
Rows per page:

Browse and explore files within this extension package

Gain full insight into all external connections.

Upgrade for full visibility.