Is SeekIt — Get 1TB Free Storage safe?

Medium risk

SeekIt sends search queries and browser context telemetry to analytics.seekit.com when users use search.seekit.com.

When a tab navigates to a SeekIt search results page with a query, the service worker records the query, previous or referring URL details, tab and window context, counters, engagement metrics, install metadata, and remote-config labels. It POSTs those fields to analytics.seekit.com/track, and also records a daily active user event on the first search of the day.

Power Search in Chromev3.5.4Chrome Web Store
45Risk
Who publishes it

Power Search in Chrome - no other listings under this identity, 1 shared hostname

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Power Search in Chrome

Shared hosts - 1 hostname

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

searchinchrome.com
Also called by 2 other listings: Ready Mail New Tab, Maps Hub Search

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeekIt Sends Your Search Queries and Tab Context to analytics.seekit.com

When you search on SeekIt, via the omnibox or search.seekit.com results, its service worker POSTs the search to analytics.seekit.com/track: term, install ID, referring domain, tab/window counts, active-tab status, and search streak.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You search using SeekIt, either from the omnibox or by opening a search.seekit.com results page with a query.

The extension did this

The background service worker separately reports your search term and details about your open tabs to SeekIt's analytics server.

This telemetry request is distinct from the request that returns your search results, and it fires on every search.

What is sent in each search_performed analytics event
  • Your search query
    best noise cancelling headphones under 200

    The exact text you searched for is sent to the analytics endpoint, separate from the request that returns your results.

  • Persistent install identifier
    ref_rzyssacVIYqisQFg25MCMeFE0UI0oXVJ

    A random ID assigned to your install and reused on every analytics event, letting SeekIt link all of your searches together over time.

  • Where you came from
    welcome.seekit.com

    The domain of the page you were on immediately before the search, sent as referring_domain and inside source_hints.

  • Open tabs and windows
    tab_count: 3, is_active_tab: false, has_multiple_windows: false

    How many tabs you have open, whether the search tab is active, and whether you have more than one window open.

  • Search history counters
    total_searches_all_time: 1, search_streak_days: 1

    A running total of every search you've made since installing SeekIt and your consecutive-day search streak.

  • Engagement score
    engagement_score: 4

    A computed score summarizing how actively you use the extension, built from your search count, streak, and session activity.

Captured request
POSThttps://analytics.seekit.com/track

200 OK

Headers
Content-Type
application/json
Body
{  "event": "search_performed",  "distinct_id": "ref_rzyssacVIYqisQFg25MCMeFE0UI0oXVJ",  "properties": {    "query": "best noise cancelling headphones under 200",    "source": "omni",    "source_hints": {      "subid": "chrome-extension",      "referrer": "https://welcome.seekit.com/chrome",      "url_source": "omni"    },    "tab_count": 3,    "is_active_tab": false,    "referring_domain": "welcome.seekit.com",    "has_multiple_windows": false,    "session_searches": 1,    "session_duration_seconds": 21,    "search_streak_days": 1,    "total_searches_all_time": 1,    "engagement_score": 4,    "extension_version": "3.5.4"  }}
The code that does this

The listener that reads your query, and the pipeline that reports it.

Readable version

Search-navigation listener (annotated)

service_worker.js
// Fires on every tab navigation. Only acts when the new URL is a// search.seekit.com results page carrying a "q" query parameter.chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {  if (changeInfo.url) {    const previousUrl = tabPreviousUrls.get(tabId) || '';    const suppressedUrl = tabRewriteSuppress.get(tabId);    if (suppressedUrl === changeInfo.url) {      tabRewriteSuppress.delete(tabId);    } else if (tabRewriteSuppress.has(tabId)) {      tabRewriteSuppress.delete(tabId);      tabPreviousUrls.set(tabId, changeInfo.url);      return;    }    try {      const url = new URL(changeInfo.url);      // Match a SeekIt search-results URL and read the query text.      if (url.hostname === 'search.seekit.com' &&          (url.pathname === '/' || url.pathname === '/search' || url.pathname === '/serp')) {        const query = url.searchParams.get('q');        if (query) {          const subid = url.searchParams.get('subid');          const isOmniboxSearch = (subid === 'chrome-extension') ||                                 (!previousUrl || previousUrl === '' || previousUrl === 'about:blank');          // Classify where the search came from (omnibox shortcut vs.          // clicking a result on the search page itself).          let source = 'unknown';          if (subid === 'chrome-extension') {            source = ANALYTICS_SOURCE.OMNI;          } else if (previousUrl && (previousUrl.includes('s1search.co') || previousUrl.includes('search.seekit.com'))) {            const urlParams = new URLSearchParams(url.search);            const hasOtherSubid = urlParams.has('subid') && urlParams.get('subid') !== 'chrome-extension';            if (hasOtherSubid) {              source = ANALYTICS_SOURCE.SERP;            } else if (!urlParams.has('subid')) {              source = ANALYTICS_SOURCE.SERP;            } else {              source = ANALYTICS_SOURCE.SERP;            }          } else if (!previousUrl || previousUrl === '' || previousUrl === 'about:blank') {            source = ANALYTICS_SOURCE.OMNI;          } else if (previousUrl && !previousUrl.includes('google.com') && !previousUrl.includes('bing.com')) {            source = ANALYTICS_SOURCE.OMNI;          } else {            source = ANALYTICS_SOURCE.OMNI;          }          if (source === ANALYTICS_SOURCE.OMNI && url.hostname === 'search.seekit.com') {            const currentUrl = new URL(changeInfo.url);            const existingRef = currentUrl.searchParams.get('ref');            const alias = await getOrCreateAlias(existingRef);            chrome.tabs.sendMessage(tabId, {              type: 'update_url_params',              ref: alias,              source: ANALYTICS_SOURCE.OMNI,              currentUrl: changeInfo.url            }).catch(() => {            });          }          // Read tab_count / is_active_tab / referring_domain /          // has_multiple_windows before the analytics call.          const contextualMeta = await getContextualSearchMetadata(tabId, previousUrl);          if (typeof SeekItAnalytics !== 'undefined' && SeekItAnalytics.trackSearch) {            // Primary path: reports the query + browser context to            // analytics.seekit.com/track via SeekItAnalytics.trackSearch.            SeekItAnalytics.trackSearch(query, source, {              source_hints: {                subid: subid || 'none',                referrer: previousUrl || 'none',                url_source: source              },              ...contextualMeta            });            // Track daily_active_user on first search of the day (search-based, not install-based)            SeekItAnalytics.trackDailyActiveOnSearch();          } else {            // Fallback path: same event, sent with a direct fetch() if the            // SeekItAnalytics module hasn't loaded yet.            await fallbackTrackSearch(query, source, {              source_hints: {                subid: subid || 'none',                referrer: previousUrl || 'none',                url_source: source              },              ...contextualMeta            });            await fallbackTrackDailyActive();          }        }      }      // Separately: flag when the user leaves SeekIt for a competing      // search engine right after a SeekIt search.      if (previousUrl && previousUrl.includes('search.seekit.com')) {        const competitorDomains = ['google.com', 'bing.com', 'duckduckgo.com', 'yahoo.com'];        for (const competitor of competitorDomains) {          if (changeInfo.url.includes(competitor)) {            if (typeof SeekItAnalytics !== 'undefined' && SeekItAnalytics.trackCompetitorPivot) {              SeekItAnalytics.trackCompetitorPivot(competitor);            }            break;          }        }      }    } catch (error) {    }    tabPreviousUrls.set(tabId, changeInfo.url);  }});

Event enrichment and POST (annotated)

js/seekit-analytics-simple.js
    // Builds the event envelope (distinct_id, timestamp, session_id) and    // POSTs it to analytics.seekit.com/track. Falls back to a local    // offline queue if the request fails.    async sendEvent(eventName, properties = {}) {      if (!this.initialized) {        await this.initialize();      }      const eventData = {        event: eventName,        distinct_id: this.userId,          // persistent per-install alias        properties: {          ...properties,          extension_version: chrome.runtime.getManifest().version,          timestamp: new Date().toISOString(),          session_id: this.sessionId        }      };      try {        const response = await fetch(this.ANALYTICS_ENDPOINT, {   // https://analytics.seekit.com/track          method: 'POST',          headers: { 'Content-Type': 'application/json' },          body: JSON.stringify(eventData)        });        if (!response.ok) {          await this.queueOfflineEvent(eventData);          return false;        }        return true;      } catch (error) {        await this.queueOfflineEvent(eventData);        return false;      }    },    // Attaches session/search-history telemetry, an engagement score,    // remote-config labels, and install/device metadata before calling    // sendEvent(). This is what turns a bare "search_performed" event    // into one carrying tab context and usage history.    async sendEventWithEnrichment(eventName, properties = {}) {      const [sessionTelemetry, configParams, installMetadata] = await Promise.all([        this.getSessionTelemetry(),      // session_searches, search_streak_days, total_searches_all_time, ...        this.getRemoteConfigParams(),    // experiment_bucket, ab_variant, feature_flags        this.getInstallMetadata()        // install_hour/day/weekend, screen_resolution, language, timezone      ]);      const engagementData = this.calculateEngagementScore(sessionTelemetry);      const enrichedProperties = {        ...properties,        ...sessionTelemetry,        ...engagementData,        ...configParams,        install_hour: installMetadata.install_hour,        install_day_of_week: installMetadata.install_day_of_week,        install_is_weekend: installMetadata.install_is_weekend,        install_time_bucket: installMetadata.install_time_bucket,        screen_resolution: installMetadata.screen_resolution,        user_language: installMetadata.language,        user_timezone: installMetadata.timezone      };      return this.sendEvent(eventName, enrichedProperties);    },    // Called on every matched search-results navigation. Updates the    // local search-streak/total counters, then sends "search_performed"    // with the query text through the enrichment pipeline above.    async trackSearch(query, source = 'omnibox', additionalProps = {}) {      this.searchesThisSession += 1;      this.lastSearchTime = Date.now();      const stored = await chrome.storage.local.get([        'total_searches_all_time',        'last_search_date',        'search_streak_days'      ]);      const today = new Date().toDateString();      const yesterday = new Date(Date.now() - 86400000).toDateString();      let newStreak = stored.search_streak_days || 0;      if (stored.last_search_date === yesterday) {        newStreak += 1;      } else if (stored.last_search_date !== today) {        newStreak = 1;      }      const newTotal = (stored.total_searches_all_time || 0) + 1;      await chrome.storage.local.set({        total_searches_all_time: newTotal,        last_search_date: today,        search_streak_days: newStreak      });      await this.sendEventWithEnrichment('search_performed', {        query: query,                                   // your exact search text        source: source,        search_number_this_session: this.searchesThisSession,        ...additionalProps                               // source_hints + tab_count/is_active_tab/etc.      });    },
Where the query and browser-context data are sent
    • analytics.seekit.com

    Receives the search_performed and daily_active_user events: your persistent install ID, search query, and browser-context fields. First-party, SeekIt's own domain.

What it can do

Permissions this extension asks for, as declared in version 3.5.4. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on searchinchrome.com

    *://*.searchinchrome.com/*

  • Read and change your data on seekit.com

    *://*.seekit.com/*

  • Schedule its own background tasks

    alarms

  • Add items to the right-click menu

    contextMenus

  • See the address and title of every tab you have open

    tabs

  • Store data in your browser

    storage

  • Run searches with your default search engine

    search

Where it sends data

Destinations our analysis observed SeekIt — Get 1TB Free Storage contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • analytics.seekit.com

    SeekIt — Get 1TB Free Storage sends data to analytics.seekit.com. No other extension we have analysed sends data here.

Updated 30 September 2026jhnhhbbkpcemehnimghkpmpdameaandj