registry  /  sweet-search  /  2.6.8

sweet-search@2.6.8

Sweet Search - SOTA Hybrid Code Search Engine with WASM CatBoost Query Router, Semantic/Lexical/Structural Search, and Multilingual Support

AI Security Review

scanned 4d ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs `sweet-search init`, optionally with `--mcp`, `--codex`, or `--codex-enable-global-hooks`.
Impact
Can influence configured coding-agent tool selection and register the local `sweet-search-mcp` command in the current project. The global `~/.codex/config.toml` path requires a separate explicit option.
Mechanism
Writes project agent instruction/configuration files and package-owned Claude hook files; optionally enables a global Codex hooks feature flag.
Rationale
The package is not install-hook malware: its only npm lifecycle hook is terminal-only and no install-time mutation, remote payload execution, secret access, exfiltration, or persistence chain was verified. However, the explicitly invoked initialization command installs persistent project-agent instructions, hooks, permission changes, and optional MCP/Codex configuration. That guarded but broad agent-facing capability warrants a warning rather than a clean verdict or publish block.
Evidence
package.jsonscripts/postinstall-banner.jsscripts/init.jsscripts/inject-agent-instructions.jsscripts/write-claude-rules.jsscripts/install-mcp-server.jsscripts/install-prompt-reminders.jsscripts/install-tool-enforcement.jsscripts/hooks/intercept-read.mjsscripts/hooks/remind-tools.mjsmcp/server.jscore/embedding/embedding-remote.jscrates/wasm-router/pkg/query_router_wasm.jscrates/wasm-router/pkg/query_router_wasm_bg.wasmCLAUDE.mdAGENTS.md
Network endpoints1
api.voyageai.com

Decision evidence

public snapshot
AI called this Suspicious at 93.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `scripts/init.js` is reached through the explicit `sweet-search init` command and can call agent integration helpers.
  • The explicit init workflow writes project AI-agent surfaces: `CLAUDE.md`, `AGENTS.md`, `.claude/rules/sweet-search.md`, `.claude/settings.json`, `.claude/hooks/sweet-search-remind-tools.mjs`, `.claude/hooks/sweet-search-intercept-read.mjs`, `.claude/skills/sweet-index/`, `.mcp.json`, and `.codex/config.toml`.
  • With the separate `--codex-enable-global-hooks` option, `scripts/init.js` can also update `~/.codex/config.toml`.
  • `scripts/install-tool-enforcement.js` modifies `.claude/settings.json` permissions and registers a `UserPromptSubmit` hook; this is a meaningful agent-control capability.
  • The copied Claude hook payloads inject persistent tool-routing guidance into agent context, including a `PreToolUse` hook that allows `Read` while suggesting package-provided search tools.
Evidence against
  • `package.json` declares only `postinstall`, which runs `scripts/postinstall-banner.js`; inspection shows it only writes a best-effort terminal banner and does not alter project files, agent configuration, persistence locations, or network state.
  • All inspected agent-control writes are initiated by `sweet-search init` and option parsing in `scripts/init.js`, not by npm `preinstall`, `install`, or `postinstall`.
  • The MCP helper registers a project-local `.mcp.json` entry for `npx -y sweet-search-mcp`; `mcp/server.js` uses stdio transport and no remote MCP endpoint was found.
  • The inspected Claude hooks neither execute external commands nor fetch data: `scripts/hooks/intercept-read.mjs` emits an allow decision and routing hint, while `scripts/hooks/remind-tools.mjs` emits a static reminder.
  • Network behavior inspected in `core/embedding/embedding-remote.js` sends user-configured embedding requests to configured provider endpoints such as `https://api.voyageai.com`; no fetch-to-eval, fetched command execution, credential collection, or exfiltration chain was found.
  • The supplied 2.6.7→2.6.8 diff has no new or changed lifecycle script, entrypoint, capability, executable, or bundled WASM artifact. The WASM loader reads the shipped `crates/wasm-router/pkg/query_router_wasm_bg.wasm` locally.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsObfuscatedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 246 file(s), 5.35 MB of source, external domains: 127.0.0.1, api.cerebras.ai, api.groq.com, api.jina.ai, api.mistral.ai, api.voyageai.com, github.com, huggingface.co, nodejs.org

Source & flagged code

5 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall-banner.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
crates/wasm-router/pkg/query_router_wasm.jsView file
266const wasmPath = `${__dirname}/query_router_wasm_bg.wasm`; L267: const wasmBytes = require('fs').readFileSync(wasmPath); L268: const wasmModule = new WebAssembly.Module(wasmBytes);
Medium
Dynamic Require

Package source references dynamic require/import behavior.

crates/wasm-router/pkg/query_router_wasm.jsView on unpkg · L266
core/indexing/index-codebase-v21.jsView file
35// enable. libuv reads this lazily on first thread pool use. L36: if (process.env.SWEET_SEARCH_UV_THREADPOOL_SIZE && !process.env.UV_THREADPOOL_SIZE) { L37: process.env.UV_THREADPOOL_SIZE = process.env.SWEET_SEARCH_UV_THREADPOOL_SIZE; ... L121: // Animated banner (best-effort; interactive TTY only, never in CI / quiet / stdin-fed runs). L122: if (!quiet && !help && !filesFromStdin && process.stdout.isTTY && !process.env.CI && !process.env.NO_BANNER && !process.env.SWEET_SEARCH_NO_BANNER) { L123: try { const { showBanner } = await import('../banner/render-banner.js'); await showBanner({ clear: true }); } catch { /* non-fatal */ } ... L136: } else { L137: applyPersistedLiModel(process.env.SWEET_SEARCH_PROJECT_ROOT || process.cwd()); L138: } ... L446: // form silently no-op'd under three real-world conditions: L447: // 1. `npm install ../sweet-search-private` (file install) symlinks L448: // `node_modules/sweet-search/` to the source — `process.argv[1]` is the
Medium
Unsafe Vm Context

Package source executes code through a VM context API.

core/indexing/index-codebase-v21.jsView on unpkg · L35
core/search/search-fusion.jsView file
41if (result.name) return String(result.name); L42: if (process.env.DEBUG_CATCHES) { L43: _fallbackKeyCount++; L44: if (_fallbackKeyCount <= 5 || _fallbackKeyCount % 100 === 0) { L45: process.stderr.write(`[search-fusion] fallback hash dedup path used (${_fallbackKeyCount})\n`); L46: }
Low
Weak Crypto

Package source references weak cryptographic algorithms.

core/search/search-fusion.jsView on unpkg · L41
crates/wasm-router/pkg/query_router_wasm_bg.wasmView file
path = crates/wasm-router/pkg/query_router_wasm_bg.wasm kind = wasm_module sizeBytes = 201196 magicHex = [redacted]
Medium
Ships Wasm Module

Package ships WebAssembly modules.

crates/wasm-router/pkg/query_router_wasm_bg.wasmView on unpkg

Findings

1 High6 Medium6 Low
HighInstall Time Lifecycle Scriptspackage.json
MediumDynamic Requirecrates/wasm-router/pkg/query_router_wasm.js
MediumUnsafe Vm Contextcore/indexing/index-codebase-v21.js
MediumNetwork
MediumEnvironment Vars
MediumShips Wasm Modulecrates/wasm-router/pkg/query_router_wasm_bg.wasm
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptocore/search/search-fusion.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings