Back to skill

Security audit

SearXNG Search CLI (Free, Self-hosted, Auto-deploy, Multi-Channel)

Security checks across malware telemetry and agentic risk

Overview

This search skill is not clearly malicious, but it deserves review because installation can run unverified shell commands, modify local service configuration, and enable autostart behavior.

Install only if you intentionally want an agent-managed local SearXNG deployment. Review the Python script and onboarding commands first, avoid running the pipe-to-shell installer blindly, do not use untrusted SEARXNG_HOST or SEARXNG_PORT values, avoid submitting secrets as searches, and enable autostart only if you accept a persistent local service.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (35)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run(cmd, check=True, cwd=None):
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, cwd=cwd)
    if check and result.returncode != 0:
        log(f"Error: {result.stderr}")
        sys.exit(1)
Confidence
97% confidence
Finding
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, cwd=cwd)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
f'{SEARXNG_DIR}/.venv/bin/python -m searx.webapp '
        f'--host {SEARXNG_HOST} --port {SEARXNG_PORT}'
    )
    subprocess.Popen(cmd, shell=True, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    import time
    for _ in range(15):
Confidence
98% confidence
Finding
subprocess.Popen(cmd, shell=True, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

Tainted flow: 'cmd' from os.environ.get (line 148, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
def run(cmd, check=True, cwd=None):
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, cwd=cwd)
    if check and result.returncode != 0:
        log(f"Error: {result.stderr}")
        sys.exit(1)
Confidence
96% confidence
Finding
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, cwd=cwd)

Tainted flow: 'cmd' from os.environ.get (line 148, credential/environment) → subprocess.Popen (code execution)

Medium
Category
Data Flow
Content
f'{SEARXNG_DIR}/.venv/bin/python -m searx.webapp '
        f'--host {SEARXNG_HOST} --port {SEARXNG_PORT}'
    )
    subprocess.Popen(cmd, shell=True, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    import time
    for _ in range(15):
Confidence
99% confidence
Finding
subprocess.Popen(cmd, shell=True, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

Tainted flow: 'req' from os.environ.get (line 46, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
f"http://{SEARXNG_HOST}:{SEARXNG_PORT}",
                headers=FORWARDED_FOR
            )
            resp = urllib.request.urlopen(req, timeout=3)
            return resp.status == 200
        except:
            import time
Confidence
91% confidence
Finding
resp = urllib.request.urlopen(req, timeout=3)

Tainted flow: 'req' from os.environ.get (line 46, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
try:
        req = urllib.request.Request(url, headers=FORWARDED_FOR)
        with urllib.request.urlopen(req, timeout=10) as resp:
            data = json.load(resp)

        results = data.get("results", [])
Confidence
92% confidence
Finding
with urllib.request.urlopen(req, timeout=10) as resp:

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The manifest presents a simple search skill, but the documented behavior implies shell execution, network access, environment use, and file writes without explicitly declaring those capabilities. This reduces transparency and consent, making it easier for a user or host system to invoke installation or service-management actions they did not expect.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill claims to perform user searches, but the documented and analyzed behavior extends into software installation, configuration editing, service persistence, process termination, and potential header spoofing. This mismatch is dangerous because users may authorize a benign-seeming search tool that can modify the local system, establish persistence, and alter network behavior beyond the stated purpose.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The README presents this as a search skill, but it also advertises installation, deployment, and lifecycle management of a SearXNG service. That expands the privilege and execution scope beyond simple information retrieval, increasing the chance that normal search requests trigger host-level changes or service operations the user did not clearly intend.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
System and service administration capabilities are not justified by the stated end-user purpose of searching and research. In an agent setting, this mismatch can lead to unnecessary privileged operations on the host, making accidental deployment, persistence, or service modification more likely.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
A skill framed as a search interface also exposes install, start, stop, restart, enable, and disable commands for a local service. That expands the trust boundary from information retrieval into host administration, creating risk of unintended system modification and persistence under a misleading interface.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
Installing software and enabling autostart are not necessary to satisfy a narrow 'search queries' purpose, so their inclusion is unjustified and increases attack surface. In context, this makes the skill more dangerous because ordinary search requests could lead users into persistent host changes and privileged operations.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
This skill claims to be a search CLI but also installs software, edits configuration, starts background services, and enables persistence. That mismatch materially increases risk because invoking a seemingly simple search tool can unexpectedly modify the host and expand the attack surface.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The code performs package installation, repository cloning, dependency setup, and service lifecycle management, all of which exceed the expected scope of a basic search utility. In an agent ecosystem, this broadens the consequences of misuse from information retrieval to arbitrary host changes and code fetching.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The script silently modifies `settings.yml`, attempts to place `limiter.toml` under `/etc`, and later writes a persistent systemd user service. These are durable system changes that users may not expect from a search helper, creating configuration drift and persistence risk.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The code deliberately sets `X-Forwarded-For: 127.0.0.1` and documents it as a bot-detection bypass by exploiting trusted proxy behavior. This is an intentional security-control evasion mechanism, not a benign local access detail, and could undermine protections in SearXNG or any service that trusts that header.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The trigger phrases are broad everyday requests like 'search this' or 'find recent AI news,' which can cause the skill to activate in ordinary conversation without a strong intent boundary. Because the skill also includes install and service-management functionality, ambiguous triggering increases the risk that a user is funneled into a higher-privilege tool than expected.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The skill does not clearly warn users that their queries will be transmitted to a self-hosted search service and possibly onward to upstream search engines. This is dangerous because users may submit sensitive prompts or identifiers without understanding the network and privacy implications.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The onboarding instructs users to fetch a remote installer over the network and pipe it directly into `sh`, which executes unreviewed code immediately. This is dangerous because a compromised upstream server, TLS interception, or installer change could lead to arbitrary code execution on the host during setup.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The installer downloads and executes a remote shell script via `curl ... | sh` without verification or prominent warning. This is dangerous because compromise of the remote source, TLS interception, or supply-chain tampering would immediately yield arbitrary code execution on the host.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill modifies application configuration and later creates a persistent service without a clear user-facing warning about those changes. Hidden persistence and config mutation are especially risky in an agent skill because users may believe they are only performing a search operation.

Unvalidated Output Injection

High
Category
Output Handling
Content
def run(cmd, check=True, cwd=None):
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, cwd=cwd)
    if check and result.returncode != 0:
        log(f"Error: {result.stderr}")
        sys.exit(1)
Confidence
96% confidence
Finding
subprocess.run(cmd, shell=True, capture_output

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
chmod +x <skill_dir>/scripts/searxng_cli.py

# 创建 symlink(如果不存在)
which searxng-search || sudo ln -sf <skill_dir>/scripts/searxng_cli.py /usr/local/bin/searxng-search

# 设置 secret(安装时会自动生成,也可预设置)
export SEARXNG_SECRET="your-secret-key"
Confidence
87% confidence
Finding
sudo

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
> 2. `uv venv --clear` 创建虚拟环境
> 3. `uv pip install -r requirements.txt` 安装依赖
> 4. 启用 JSON API(修改 `settings.yml`)
> 5. 复制 `limiter.toml` 到 `/etc/searxng/`(需要 sudo 或目录已存在)
> 6. 生成 secret 并启动服务

### 验证
Confidence
83% confidence
Finding
sudo

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
| 错误 | 原因 | 解决 |
|------|------|------|
| `command not found: searxng-search` | symlink 未创建 | `sudo ln -sf <skill_dir>/scripts/searxng_cli.py /usr/local/bin/searxng-search` |
| `command not found: uv` | uv 未安装或 PATH 未生效 | Step 2 重新安装,`export PATH="$HOME/.local/bin:$PATH"` |
| `TypeError: schema of limiter.toml is invalid` | `/etc/searxng/limiter.toml` 格式错误或为空 | `sudo cp ~/projects/searxng/searx/limiter.toml /etc/searxng/limiter.toml` |
| `403 Forbidden` (API 请求) | Bot detection 拦截(缺少 `X-Forwarded-For` header) | 确保 limiter.toml 存在且格式正确(使用源码默认文件);CLI 已内置 header 处理 |
Confidence
84% confidence
Finding
sudo

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.