Back to glossary

Searchjacking

Searchjacking is the takeover of a browser's default search engine, usually by an extension, so every query passes through an operator's server first.

Also known as Search hijacking, Browser search hijacking, Search hijacker, Search engine hijacking

Searchjacking, also called search hijacking, is the takeover of a browser's default search engine, usually by an extension, so every query reaches an operator's server before a real search engine. The operator logs the query, appends a Yahoo or Bing partner ID to earn syndication revenue, and decides per request where the user lands.

The most important fact about searchjacking is that it needs no code. In our Searchjacked investigation, published in October 2026, we tracked 319 extensions, installed by roughly 13.4 million users since 2016, that exist only to capture search queries. Many are a manifest.json file and three icons. Chrome treats that shape as the least risky kind of search extension: the install prompt names a domain, and Chromium skips its later "Change back to Google Search?" dialog for it.

Our position: an extension whose only function is to route your searches through an operator's server, hidden from store search and pushed through junk ads, is malware, not a merely unwanted program. A permission review scores it as harmless, because the harm lives on the server, where the destination of every query is decided after install and after store review. Browsers should tell users where their searches end up, not just which domain receives them first.

How does a browser decide where a search goes?

#

A browser decides where a search goes by filling a URL template. When you type words that are not a URL into the address bar, the browser substitutes them for {searchTerms} in the default engine's template and navigates there. The search engine is just that string.

Partner deals ride inside the template. A 2015 Mozilla bug that updated the Yahoo partner build of Firefox set this search URL:

Plain text
https://search.yahoo.com/yhs/search?ei=UTF-8&fr=chrf-yff37&hspart=mozilla&hsimp=yhs-002&p={query}

hspart=mozilla and hsimp=yhs-002 identify the partner that delivered the search, so Yahoo knows whom to pay. Keep those two fields in mind. Searchjackers use exactly the same ones.

Chrome resolves the effective engine from layers. Chromium's search engine code names five sources: a country fallback, the user's choice, an extension override, mandatory enterprise policy, and recommended enterprise policy. An extension override beats the user's choice, and mandatory policy beats the extension.

Browsers defend the user's stored choice against tampering. Chromium signs sensitive preferences with HMACs in its Secure Preferences file. As of November 2026, Chromium's source also keeps a mirrored copy of the default engine and resets a tampered one on Windows and macOS, a feature named kResetTamperedDefaultSearchEngine that is enabled by default. That is why older hijackers had to work hard. Microsoft's analysis of Adrozek in December 2020 found it patching the browser's integrity check with a two-byte change, and it hit over 30,000 devices a day at its August 2020 peak.

Searchjacking skips every one of those defenses. Chrome's extension quality guidelines say it plainly: "The only supported way to change the default web search settings using an extension is via the Settings Overrides API." The integrity checks guard the user's own setting. The extension layer above it is the sanctioned path, and it needs no forgery.

How do browser extensions hijack searches?

#

Browser extensions hijack searches by declaring a search_provider block under chrome_settings_overrides in manifest.json, with is_default set to true. Apart from three icon files, this manifest is the entire Safe Game Search extension from our research:

JSON
{
  "update_url": "https://clients2.google.com/service/update2/crx",
  "manifest_version": 3,
  "version": "1.1",
  "name": "Safe Game Search",
  "short_name": "Game Safe Search",
  "description": "Real-time safety alerts for game searches and risky game websites",
  "default_locale": "en",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "chrome_settings_overrides": {
    "search_provider": {
      "name": "Safe Game",
      "keyword": "Safe Game Search",
      "is_default": true,
      "encoding": "UTF-8",
      "favicon_url": "https://safesearchgame.com/favicon.ico",
      "search_url": "https://search.safesearchgame.com/query?q={searchTerms}",
      "suggest_url": "https://suggest.safesearchgame.com/querying/autocomplete?query={searchTerms}"
    }
  }
}

There are no permissions, no service worker, no content scripts, and no UI. Nothing in the package executes. The browser does all the work, and the operator's server does the rest. That is why browser extension security reviews that start from the permission list find nothing to flag.

Chrome checks a search override at three points. Each check is weaker than it looks.

The install prompt names a host, not a destination. Chrome converts the override into an internal permission whose warning reads "Change your search settings to:" followed by the host from search_url, minus any www. prefix. For Safe Game Search the user sees search.safesearchgame.com, which looks like a search engine. Nothing says the server forwards queries to Yahoo, records them, or can send them anywhere else.

Domain verification proves ownership, not behavior. Chrome's settings override documentation requires the publisher to verify the search_url domain in Google Search Console. That shows the publisher controls the proxy. It says nothing about what the proxy does with a query.

The post-install dialog exempts exactly this shape. Chrome can ask "Change back to Google Search?" after an extension takes over search. Chromium skips that dialog for a "simple override" extension, one whose manifest contains only keys from a fixed allowlist such as name, icons, default_locale, update_url, and chrome_settings_overrides. The source comment says those keys must not give the extension "any additional capability" beyond what the site would have if the user changed search by hand. A Chromium browser test spells out the consequence: a manifest-only override gets no dialog, and an update that adds "permissions": ["storage"] makes the dialog appear.

That allowlist is where the trust assumption breaks. It treats the search host as a site the user picked. In searchjacking, the user picked a "PDF finder" from a pop-under ad, and the host is a redirector run by someone else. Applying the least privilege principle to the browser makes the extension look ideal, because it can do almost nothing locally. All of its power is on the server.

You can check any manifest against Chrome's rules. This script reproduces the install warning and the simple-override test from Chromium's source:

Python
#!/usr/bin/env python3
"""Report what Chrome will show for an extension that overrides default search."""
import json, sys
from urllib.parse import urlsplit

# Keys Chromium accepts in a "simple override" extension, from
# chrome/browser/ui/extensions/extensions_overrides/simple_overrides.cc
SIMPLE_OVERRIDE_KEYS = {
    "author", "about_page", "current_locale", "default_locale", "description",
    "differential_fingerprint", "homepage_url", "icons", "icon_variants", "key",
    "manifest_version", "minimum_chrome_version", "name", "offline_enabled",
    "options_page", "options_ui", "chrome_settings_overrides", "short_name",
    "update_url", "version", "version_name", "incognito",
}

manifest = json.load(open(sys.argv[1], encoding="utf-8-sig"))
sp = manifest.get("chrome_settings_overrides", {}).get("search_provider")
if not sp:
    sys.exit("no search_provider override")

host = urlsplit(sp["search_url"]).hostname.removeprefix("www.")
extra = sorted(set(manifest) - SIMPLE_OVERRIDE_KEYS)

print(f"search_url:      {sp['search_url']}")
print(f"is_default:      {sp.get('is_default')}")
print(f"install warning: Change your search settings to: {host}")
print(f"permissions:     {manifest.get('permissions', [])}")
print(f"simple override: {not extra}" + (f" (extra keys: {extra})" if extra else ""))

Run against Safe Game Search, and against the same manifest with one permission added:

Shell Session
$ python3 check_search_override.py safe-game-search/manifest.json
search_url:      https://search.safesearchgame.com/query?q={searchTerms}
is_default:      True
install warning: Change your search settings to: search.safesearchgame.com
permissions:     []
simple override: True

$ python3 check_search_override.py with-storage/manifest.json
search_url:      https://search.safesearchgame.com/query?q={searchTerms}
is_default:      True
install warning: Change your search settings to: search.safesearchgame.com
permissions:     ['storage']
simple override: False (extra keys: ['permissions'])

Chromium is removing the exemption, slowly. The dialog code now reads: "Historically, 'Simple Overrides' were exempt from this dialog. We are removing that exemption." The change sits behind a feature named kSearchEngineUnconditionalDialog. As of November 2026, that feature is disabled by default in Chromium's main branch, and the code grandfathers extensions installed before enforcement begins.

Firefox draws the line differently. MDN says is_default "is opt-in and the user will only be asked the first time the extension is installed," and Firefox requires search_url to use HTTPS. Chrome's manifest parser accepts http or https. Chrome documents the settings override API as available on Windows and Mac.

Why do searchjackers route queries through a proxy?

#

Searchjackers route queries through a proxy because the proxy is where the money, the data, and the control sit. Yahoo and Microsoft run search syndication programs that share ad revenue with partners who bring them searches. Yahoo identifies the partner with hspart and hsimp, the same fields in Firefox's 2015 template. Bing uses a PC partner code and a PTAG sub-ID.

An extension could put its partner tags straight into search_url. The operators we tracked point search_url at their own server instead, which then redirects. That indirection buys three things:

  • An accounting record. The operator can reconcile its own count of searches against what Yahoo or Bing pays.
  • A complete capture point. Every query passes through the operator's server, often tied to a unique identifier. That is telemetry whose payload is the user's full search history.
  • A programmable redirect. The destination is chosen on the server, per request, after install and after review.

Predator Search, an extension with 50,000 users, shows the third point in practice. We sent six identical searches through its proxy, and they ended in four different places.

  1. 1Address bar

    The user types a query. Chrome fills the extension's template: https://search.<operator>/query?q={searchTerms}
  2. 2Operator's proxy

    Logs the query, often tied to a unique identifier. Picks a destination for this request and redirects.
  3. 3Destination, chosen per request

    Six identical searches through Predator Search's proxy ended in four places:
    Paid resultsYahoo with hspart=sz&hsimp=yhs-026 Landing pagesearchlio.net Second hopsearchtosearch.com to mcftink.com, then Yahoo ErrorCloudflare non-responsive page

    Same mechanism, not observedA phishing page or malware lure served only for chosen queries, regions, or users.

Figure 1. The extension never changed between searches. The proxy chose each destination as the query arrived.

Figure 1 in text: a query typed in the address bar goes first to the operator's proxy, which logs it, often tied to a unique identifier, and redirects it to a destination chosen for that request. For Predator Search, six identical searches produced four outcomes: Yahoo results tagged hspart=sz&hsimp=yhs-026, a landing page on searchlio.net, a hop through searchtosearch.com to a second results domain, mcftink.com, and then Yahoo, and a Cloudflare non-responsive error page. The extension never changed between searches. The same mechanism could serve a phishing page or malware lure for chosen queries, regions, or users; we did not observe that in this set.

The redirect is the dangerous part. A proxy that sends almost every search to real Yahoo results can send one chosen query, or every query from one IP range, to a phishing page. That works like a traffic distribution system, and it needs no extension update, so no store review or update check ever sees it. In our Searchjacked research, most redirects only appended partner tags. We also saw a repeated search redirected to Google's homepage without partner tags, while other searches still went to Bing. Selection per request is already happening.

How searchjacking extensions get installed and stay hidden

#

Searchjacking extensions are pushed, not found. Most of the ones we tracked are unlisted in the Chrome Web Store, so anyone with the link can install them but store search never shows them. Users arrive through low-quality pop-over and pop-under ads that promise to "Search PDFs" or "Find Manuals," land on a branded page with one install button, and sometimes get redirected to the listing automatically.

The operators work at volume. Intango LTD has published about 111 extensions since 2018, reaching roughly 2.2 million installs across about 279 domains. Each extension got its own domain and its own admin@ mailbox, so every listing looked like an independent small publisher. The 2024 SecuryBrowse wave, first documented by Secure Annex, accounts for 58 extensions and about 4.9 million users, with security brands such as "Fire Shield" and "WatchTower." Counted as one extension, the 319 we tracked would rank among the top 25 Chrome extensions by users.

Takedowns do not end a campaign. Domains often stay live after their extensions are removed, and new lures appear quickly. Finding the operators is a threat intelligence problem: we pivot from the extension ID in the store URL to the company named in its privacy policy, then to Google Ads Transparency to see every ad that advertiser buys, and use Censys and urlscan queries to fingerprint landing pages at scale.

The most durable indicators of compromise are partner IDs, not domains. Domains rotate per extension, while a syndication account is what gets paid. hspart=iba marks Intango's Yahoo account, and Bing PC=3QCV and PC=3CGP mark the SecuryBrowse cluster. One partner ID can tie dozens of unrelated-looking listings to one operator.

Searchjacking vs. SEO poisoning, affiliate hijacking, and browser hijackers

#

Searchjacking is often confused with neighboring techniques that also abuse search or browsing for money. The difference is what the attacker controls and whether anything runs in the browser.

TechniqueWhat the attacker controlsHow it worksCode in the victim's browserExample
SearchjackingThe default search engineA chrome_settings_overrides entry points search at a proxy that logs each query and redirects itNone needed319 Searchjacked extensions, about 13.4 million users
SEO poisoningWhere attacker pages rank in genuine search resultsManipulating the signals search engines use to rank pagesNone; nothing is installedCatalogued as MITRE ATT&CK T1608.006
Affiliate hijackingThe commission on a purchaseA content script rewrites shopping links to carry the operator's affiliate tagContent scripts and host permissionsAmazon Ads Blocker injected the tag 10xprofit-20
Browser modifier malwareBrowser settings, files, and binariesNative malware edits preference files and patches integrity checksNative malware on the machineAdrozek, over 30,000 devices a day in August 2020

The affiliate hijacking row comes from our analysis of Amazon Ads Blocker, which rewrote Amazon links to carry its own tag. It needed content scripts and host permissions. A searchjacker needs neither.

Two named reports share the root word, and neither is the technique itself. SearchJack is MalExt Sentry's June 9, 2026 report on 23 Chrome extensions from 22 publishers with about 758,000 users. Searchjacked is our October 2026 report on 319 extensions. Both describe searchjacking campaigns.

A new-tab extension with a search box is not automatically searchjacking. In the 152 live wallpaper extensions we analyzed, the search box called chrome.search.query with no engine override, which sends the query to whatever engine the user already set.

How do you detect and remove searchjacking?

#

You detect searchjacking by checking who controls the default search engine, and you remove it by removing that extension. In Chrome, open Settings and look for a box that reads "An extension, [extension name], is controlling this setting." Google's help page says that when you remove the extension, your settings return to how they were before you installed it. You cannot keep the extension and refuse its change.

Then confirm the fix by searching and watching the first URL. If the first hop is not your engine, something else still controls search. Treat the extension as a breach of your search history, not a preference glitch: every address-bar search you made while it was installed went to its operator.

To find search overrides across a machine, grep the installed manifests. On macOS, Chrome keeps one directory per extension version under each profile:

Bash
grep -l '"search_provider"' \
  ~/Library/Application\ Support/Google/Chrome/*/Extensions/*/*/manifest.json

On Windows, the same tree is under %LOCALAPPDATA%\Google\Chrome\User Data. Any hit deserves a look at its search_url host and at where that host redirects.

On a managed fleet, lock the engine with policy. Setting DefaultSearchProviderEnabled to true and DefaultSearchProviderSearchURL to an approved HTTPS template makes policy the controlling source. Chromium's own code says a default engine "set (or disabled) by mandatory enterprise policy takes precedence over the extension's."

Every control has a cost and a blind spot:

ControlWhat it catchesWhat it misses
Chrome install warningNames the search host the extension will useWhere that host forwards queries, and who operates it
"Change back?" dialogSearch overrides bundled with other capabilitiesSimple overrides, unless kSearchEngineUnconditionalDialog is enabled; extensions installed before enforcement
Permission reviewExtensions that request risky browser APIsSearchjackers, which request none
Store review and Search Console verificationPolicy violations at submission, and who owns the search domainServer-side behavior after approval
DefaultSearchProviderSearchURL policyEvery extension override on managed browsersUnmanaged browsers and personal profiles; users lose engine choice
Static analysis of the packageThe search host and any hard-coded partner tagsWhich destination the proxy picks for each query
Live redirect testingPartner IDs and destinations the proxy actually servesDestinations served only to chosen users, regions, or queries

Verdict: on a managed fleet, set the search policy, because it is the only control that makes every override irrelevant. Everywhere else, judge a search extension by where its search_url redirects, not by its permission list.

Static analysis has a limit too, including ours. Socket's Chrome extension analysis reads an extension's manifest and code and flags risky updates. That shows the search_url host and any partner tags hard-coded in the package. It cannot show which destination the proxy picks for a given query. In the Searchjacked research, that took sending live searches through each proxy.

The fix belongs in the browser

#

Chromium's planned dialog would still name the extension's search host, the same host the install prompt shows. Neither tells the user whether a host like search.safesearchgame.com is a search engine or a redirector that resells each query under someone else's partner ID. The browser is the one party that sees the whole chain on every search, because it follows each redirect. Until it shows users where their searches actually end up, and treats a search host that redirects as behavior worth judging, searchjacking stays a manifest away.