Is Search Tool (AI) safe?
We analyzed Search Tool (AI) version 1.3.1's actual code and gave it a 55/100 trust score. This is a useful but high-access search and AI extension with…
Bottom line
This is a useful but high-access search and AI extension with meaningful privacy and page-content risks.
What it can access
It runs across all websites, can read visible page text, history, and bookmarks, and can send selected content to AI services; this exceeds basic search needs. [Q1][Q3][Q6]
Security weaknesses
Remote AI answers are inserted as active webpage content, allowing deceptive links, images, or forms to appear in pages. [Q2][Q24]
Signs of misuse
The extension sends page content to configured AI services and can disclose visited domains to an icon service, though these actions are tied to optional features. [Q6][Q12]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It requests all-site, all-frame content-script access plus history, bookmarks, storage, activeTab, and context menus. That is much broader than basic search switching, but it supports its optional page summary, selection toolbar, and history suggestions.
Declares history, bookmarks, activeTab, storage, and a content script matching <all_urls> with all_frames enabled. — manifest.json:permissions and content_scripts
Returns document.body.innerText or documentElement.innerText to the service worker. — js/content.js:getPageContent message handler
Which websites can it run on, and can it read or change what appears on those pages?
It injects search toolbars and AI dialogs into webpages. AI replies and summaries are assigned to innerHTML without sanitization, so a remote response can place deceptive links, images, or forms into the page.
Builds overlay elements in document.body and inserts summary and chat reply strings through innerHTML. — js/content.js:showSummaryDialog and showLLMChatDialog
The default prompts explicitly instruct the remote model to return innerHTML. — _locales/en/messages.json:llmPrompt and llmSystemPrompt
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
It can access full page text, selected text, current page URLs and search terms, browser history, bookmarks, user chat prompts, search queries, and configured AI credentials. It does not request cookie access.
Reads the user's selection and the current document's full innerText. — js/content.js:getSelectText and getPageContent
Searches chrome.bookmarks and chrome.history for popup suggestions. — js/popup.js:queryMatch
Declares history and bookmarks but not cookies. — manifest.json:permissions
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
It stores search engines, feature settings, cached icons, AI services definitions, prompts, chat-menu templates, and arbitrary request headers in extension storage. The example configuration puts an AI services key in headers stored by chrome.storage.sync.
Loads and saves search, UI, history, and LLM configuration using chrome.storage.sync and icon data using local storage. — js/options.js:init and onSubmit
Shows Authorization: Bearer ${API_KEY} inside the persisted model configuration. — _locales/en/messages.json:llmModelsJsonPlaceholder
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
No evidence of this behavior was found in the reviewed package.
Declares no capture or sensor permission. — manifest.json:permissions
No getUserMedia, getDisplayMedia, geolocation, or media-capture call was found. — js/*.js:media API review
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
User-invoked AI actions send full page text, selected text, prompts, and conversation history to the configured model services. Optional suggestions send queries to Bing or Google, and history results cause visited domains to be sent to icon.horse for favicons.
Posts constructed messages and configured headers to the active model's endpoint. — js/background.js:callModel, summarizeContent, and chatWithLLMMenu
Queries remote suggestion services and creates https://icon.horse/icon/<history-domain> image URLs. — js/popup.js:googleSuggest, bingSuggest, and queryMatch
Does it download or run code, settings, or instructions supplied by a remote server?
No evidence of this behavior was found in the reviewed package.
All extension entry points are packaged scripts and the extension-page CSP permits only self-hosted scripts. — manifest.json:background, content_security_policy, and content_scripts
Parses remote responses as JSON and selects a configured response field rather than executing it. — js/background.js:callModel
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
The page access starts automatically on every frame, but full-page AI transmission requires the user to choose the summary command and AI chat requires a configured menu action. History and remote query suggestions run only when those optional settings are enabled.
Loads js/content.js at document_end in all frames on all URLs. — manifest.json:content_scripts
Requests page content and calls the model after the corresponding user context-menu action. — js/background.js:contextMenus.onClicked
Checks popupSuggestEnabled and popupHistoryEnabled before using those sources. — js/popup.js:querySearch
Can it change important browser settings, including your proxy, search engine, homepage, privacy settings, or other extensions?
No evidence of this behavior was found in the reviewed package.
Requests no search, proxy, privacy, management, declarativeNetRequest, or webRequest permission. — manifest.json:permissions
Opens or updates a tab with a configured search URL. — js/background.js:context-menu and toggle-search handlers
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
Application and vendor scripts are production-minified and source maps are absent. The important browser services, services construction, page insertion, and feature gates remain traceable, so this is reduced readability rather than strong concealment.
Contains roughly 1.2 MB of minified Vue, Element Plus, Axios, and support code. — js/chunk-vendors.js:entire file
Lists no source-map files. — inventory.json:files
Does it use eval(), new Function(), or string-based timers to turn text into executable code?
No evidence of this behavior was found in the reviewed package.
Falls back to new Function('return this') only if globalThis and ordinary this resolution are unavailable. — js/popup.js:webpack bootstrap l.g
Contains the same packaged runtime fallback; no eval or string-based timer was found in application logic. — js/options.js:webpack bootstrap
Does it track the websites, pages, searches, or links you visit?
It has permission to search browser history and uses that history for optional local suggestions. When enabled, each result's domain is embedded in an icon.horse favicon URL, disclosing visited domains to that service; I found no continuous upload of complete browsing history.
Calls chrome.history.search and chrome.bookmarks.search after the user types in the popup. — js/popup.js:queryMatch
Builds an image URL of https://icon.horse/icon/${hostname} for matched history items. — js/popup.js:queryMatch result formatting
History suggestions are disabled by default and can be enabled in settings. — js/options.js:popupHistoryEnabled setting
Does it create a persistent ID or browser fingerprint to recognize you?
No evidence of this behavior was found in the reviewed package.
Stored keys represent settings, models, prompts, and icons; no UUID generation or analytics submission path was found. — js/*.js:storage and network review
Does it send cookies, session details, authentication data, or page contents elsewhere?
It can store and transmit an AI provider services key because arbitrary model headers are saved in Chrome sync storage and copied into fetch requests. It does not read website passwords, cookies, login forms, or session tokens.
The example uses an Authorization Bearer API key in model headers. — _locales/en/messages.json:llmModelsJsonPlaceholder
Substitutes configured values into headers and passes them directly to fetch. — js/background.js:buildConfig and callModel
Does not request cookies. — manifest.json:permissions
Does it record typing, form entries, clipboard contents, or screenshots?
It monitors mouse selection on every page and can automatically copy selected text to the clipboard when that option is enabled. It does not read arbitrary clipboard contents or log keystrokes.
Reads document selection after mouseup and calls navigator.clipboard.writeText when select2clipboard is enabled. — js/content.js:mouseup listener and copySelectTxt
The automatic-copy feature is configurable and disabled by default. — js/options.js:select2clipboard setting
Can a website or remote server send commands that make the extension take actions?
No evidence of this behavior was found in the reviewed package.
Returns a configured field from the remote model's JSON response as an untrusted string. — js/background.js:callModel
Places remote answer strings into page DOM through innerHTML without sanitization. — js/content.js:showSummaryDialog d and showLLMChatDialog r
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Default Google, Bing, Baidu, Sogou, and Douban URLs contain only the search placeholder and no affiliate parameter. — _locales/en/messages.json:defaultEnginesConfig
Replaces %s with the selected query and opens that configured URL. — js/background.js:context-menu handler
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
No evidence of this behavior was found in the reviewed package.
Declares no webRequest, declarativeNetRequest, downloads, debugger, or proxy permission. — manifest.json:permissions
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
No nativeMessaging permission is declared. — manifest.json:permissions
No application endpoint targets localhost, loopback addresses, or a native host. — js/*.js:endpoint review
Does it decode, decrypt, or unpack hidden data and then execute or inject it?
No evidence of this behavior was found in the reviewed package.
Uses response.json and property traversal without an execution sink. — js/background.js:callModel
Converts fetched image blobs to data URLs for icon display. — js/options.js:fetchIconData
Can ordinary websites access privileged extension features through messaging or exposed files?
No evidence of this behavior was found in the reviewed package.
Contains no externally_connectable declaration. — manifest.json:top-level fields
Handles menu updates and model chats from packaged extension contexts. — js/background.js:runtime.onMessage
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Persists the switches, endpoint JSON, prompts, and custom menu definitions. — js/options.js:settings and llmConfig
Conditionally activates page features from the saved settings. — js/content.js:storage initialization
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Contains UI, search, storage, and HTTP client code without mining loops, worker pools, or mining protocols. — js/*.js:computation and worker review
Does it change form fields or where a form sends its information?
It does not rewrite existing page forms, but unsanitized remote AI HTML is inserted into the page and can add new inputs, forms, or links with attacker-chosen destinations. The extension also adds its own chat input and controls.
Interpolates remote summary and reply strings into innerHTML inside the current page. — js/content.js:showSummaryDialog and showLLMChatDialog
Directs the model to produce HTML tags, making active markup an expected response format. — _locales/en/messages.json:llmSystemPrompt