Back to skill

Security audit

Ask Search

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real SearxNG search helper, but its installer and advanced proxy guidance create risks users should review before installing.

Review before installing. Prefer installing to a user-writable bin directory rather than running the installer with sudo, or fix the temporary-file handling first. Pin Docker and Python dependency versions, keep SEARXNG_URL local or trusted, and avoid the documented persistent proxy or logged-in browser workflows unless you understand the privacy, credential, and policy implications.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:29
Finding
Predictable Temporary File Allows Privileged File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:29-37` **Vulnerability Type**: Predictable temporary file and symlink-following file write **Risk Level**: High when the installer runs with elevated privileges; otherwise Medium ### Vulnerable Code ```bash # Replace placeholder with actual path WRAPPER="${WRAPPER/COREPATH/$SCRIPT_DIR/scripts/core.py}" echo "$WRAPPER" > /tmp/ask-search-wrapper install -m 755 /tmp/ask-search-wrapper "$INSTALL_BIN/ask-search" rm -f /tmp/ask-search-wrapper echo "✓ ask-search installed to $INSTALL_BIN/ask-search" ``` ### Technical Analysis The installer writes wrapper content to the fixed, globally predictable path `/tmp/ask-search-wrapper`. It neither securely creates the file nor verifies that the path is a regular file owned by the current process. On systems that do not enforce effective protected-symlink or protected-regular-file restrictions, another local user can create this path before installation as a symbolic link to another file. The shell redirection performed by: ```bash echo "$WRAPPER" > /tmp/ask-search-wrapper ``` can then follow the symbolic link and overwrite its target using the installer's privileges. The risk is especially significant because installation into the default `/usr/local/bin` commonly causes users to invoke the script with `sudo`. Some modern Linux configurations mitigate portions of this attack through `fs.protected_symlinks` and `fs.protected_regular`, but the script must not rely on optional operating-system hardening. ### Attack Path 1. A local attacker predicts that a privileged user will run `install.sh`. 2. The attacker creates `/tmp/ask-search-wrapper` as a symbolic link to a file targeted for overwrite. 3. The administrator runs the installer with elevated privileges. 4. Shell redirection follows the attacker-controlled path and writes the generated wrapper into the target file. 5. Depending on the selected target, the attacker may corrupt system configuration o ...[truncated 472 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Avoid using a shared temporary file. Install the generated wrapper directly from standard input where supported, or securely create a private temporary file: ```bash TMP_WRAPPER="$(mktemp "${TMPDIR:-/tmp}/ask-search-wrapper.XXXXXX")" trap 'rm -f -- "$TMP_WRAPPER"' EXIT printf '%s\n' "$WRAPPER" > "$TMP_WRAPPER" chmod 755 "$TMP_WRAPPER" install -m 755 -- "$TMP_WRAPPER" "$INSTALL_BIN/ask-search" ``` Additional hardening should include: - Set a restrictive `umask`, such as `umask 077`, before creating temporary files. - Quote every path and use `--` before path operands. - Validate that `INSTALL_BIN` is an expected directory. - Do not run the entire installer as root when only the final installation step requires elevated privileges. - Prefer packaging mechanisms that install immutable project files directly rather than constructing executables under `/tmp`. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:72
Finding
Unpinned Python Package and Container Image Create Supply-Chain Exposure<![CDATA[ ## Vulnerability Details **File Location**: `README.md:72-75`, `README.md:141`, and `mcp/server.py:6,25` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code The SearxNG instructions use a floating container image reference: ```bash # Docker (recommended) docker run -d --name searxng \ -p 127.0.0.1:8080:8080 \ -e SEARXNG_SECRET_KEY=your-secret-key \ searxng/searxng ``` The MCP dependency is installed without a version or integrity constraint: ```text Requires: `pip install mcp` ``` The same unpinned command is repeated by the MCP server: ```python Install: pip install mcp ``` ```python except ImportError: print("Error: mcp package not installed. Run: pip install mcp", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis Both installation paths resolve mutable third-party artifacts at installation time: - `pip install mcp` installs whichever release currently satisfies the package index's default resolution. - `searxng/searxng` without a version tag or immutable digest normally resolves a mutable default tag. Consequently, installations performed at different times may execute different code despite using the same audited project revision. A compromised publisher account, registry, package-index path, or unexpectedly incompatible upstream release could introduce malicious or unsafe behavior after this project has been reviewed. The project does not automatically run these installation commands, so exploitation requires a user to follow the documented setup procedure. Nevertheless, dependency installation executes third-party code and therefore forms part of the project's security boundary. ### Attack Path 1. An upstream package release or container tag is compromised, replaced, or updated with unsafe code. 2. A user follows the documented `pip install mcp` or `docker run ... searxng/searxng` instructions. 3. The package manager or container runtime downloads the current ...[truncated 753 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the Python dependency to a reviewed version: ```bash python3 -m pip install "mcp==<reviewed-version>" ``` - Prefer a locked requirements file containing cryptographic hashes: ```text mcp==<reviewed-version> \ --hash=sha256:<verified-hash> ``` - Pin the SearxNG image to a reviewed release and immutable digest: ```bash docker run ... searxng/searxng:<reviewed-version>@sha256:<verified-digest> ``` - Document a controlled upgrade and review process rather than silently following floating releases. - Use an isolated virtual environment for the MCP server. - Run the container without unnecessary capabilities, mounts, or host-network access. - Replace the placeholder SearxNG secret guidance with instructions for generating a high-entropy secret. ]]>

T06 · System Persistence

Note
Location
README.md:223
Finding
Documentation Recommends a Persistent System-Wide SSH Proxy Service<![CDATA[ ## Vulnerability Details **File Location**: `README.md:223-239` **Vulnerability Type**: Optional cross-session network-tunnel persistence **Risk Level**: Low ### Vulnerable Code ```ini # /etc/systemd/system/socks-proxy.service [Unit] Description=SSH SOCKS Proxy for web scraping After=network.target [Service] Type=simple ExecStart=/usr/bin/ssh -N -D 127.0.0.1:1082 -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes user@your-home-machine Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` ### Technical Analysis The documentation recommends creating a system-wide systemd unit that establishes an SSH dynamic forwarding tunnel and restarts it indefinitely. If installed and enabled, the tunnel survives individual Skill executions and user sessions. This persistence is not installed by `install.sh`, is explicitly presented as an optional workaround, and does not constitute a hidden backdoor. However, a persistent system service exceeds the minimum privileges required for the declared SearxNG query functionality. The example also omits explicit host-key policy, a dedicated restricted account, service sandboxing, and SSH destination restrictions. The service binds the SOCKS listener to loopback, which limits direct remote access. Nevertheless, local processes can use the proxy, and the persistent SSH connection expands the security boundary to the configured remote machine. ### Attack Path 1. A user follows the advanced workaround and writes the unit into `/etc/systemd/system/`. 2. The user enables and starts the service. 3. The system opens an SSH connection to the configured machine and exposes a SOCKS listener on `127.0.0.1:1082`. 4. The service automatically reconnects after failure and can start at boot. 5. A malicious local process may use the listener, or compromise of the SSH account or remote endpoint may affect traffic and network reachability associated with the tunnel. ### Impact Assessment ...[truncated 401 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the persistent system service from the primary setup instructions and place it in a clearly marked advanced security section. - Prefer an on-demand tunnel that terminates when the fetch operation finishes. - If persistence is required, use a per-user systemd unit instead of a system-wide service. - Use a dedicated, minimally privileged SSH account and key. - Restrict the key in the remote `authorized_keys` configuration and prevent shell, agent, and unrelated forwarding access where compatible with the intended tunnel. - Verify and pin the remote host key through a controlled `known_hosts` file. - Add systemd sandboxing directives such as `NoNewPrivileges=yes`, `PrivateTmp=yes`, and appropriate filesystem restrictions. - Document how to stop, disable, and remove the service. - Retain the loopback-only SOCKS bind and do not expose the listener on wildcard interfaces. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "$WRAPPER" > /tmp/ask-search-wrapper

install -m 755 /tmp/ask-search-wrapper "$INSTALL_BIN/ask-search"
rm -f /tmp/ask-search-wrapper
echo "✓ ask-search installed to $INSTALL_BIN/ask-search"

# Test
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README provides operational guidance for using residential proxies, headless browsers, archive caches, and logged-in sessions to access content that may otherwise be blocked, but omits clear warnings about privacy, credential exposure, legal, and terms-of-service risks. In an agent-skill context, such guidance can normalize risky automation patterns and encourage users to route sensitive browsing or authenticated access through improvised infrastructure without adequate safeguards.

External Transmission

Medium
Category
Data Exfiltration
Content
ssh -f -N -D 127.0.0.1:1082 user@your-home-machine

# Then fetch through the proxy:
curl -x socks5h://127.0.0.1:1082 "https://reddit.com/r/example/comments/xxx.json"
```

For Reddit specifically, append `.json` to any post URL for structured data:
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill exposes capabilities that imply shell, network, and environment access, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. This creates an overbroad trust boundary: an agent or runtime may grant more capability than a user expects, and reviewers cannot easily verify what external access the skill actually needs.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
url = _search_url() + "?" + urllib.parse.urlencode(params)
    # Use subprocess curl to avoid urllib HTTP/1.0 compatibility issues
    result = subprocess.run(
        ["curl", "-s", "--max-time", "15", url],
        capture_output=True, text=True, timeout=20
    )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Intent-Code Divergence

Low
Confidence
82% confidence
Finding
Lines L005-L006 describe the skill as a self-hosted, privacy-focused web search tool. Later sections (L189-L293) document techniques for fetching full page content via curl, SSH SOCKS proxies, archive caches, and Playwright, which goes beyond simple search and contradicts the narrow framing of the skill's behavior in the README narrative.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
Lines L191-L202 state that ask-search returns URLs and snippets from search indexes, which accurately limits the tool's direct function. However, the surrounding documentation immediately expands into operational guidance for obtaining full page content, creating an intent-level contradiction in the documentation about whether the skill is just search or part of a broader scraping workflow.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The script writes a temporary wrapper file and installs it into a system-wide binary directory, which modifies the user's filesystem and potentially requires elevated privileges. Although the script prints that it is installing ask-search, it does not clearly warn about creating files in /tmp and /usr/local/bin or prompt for confirmation.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Missing User Warnings

Low
Confidence
93% confidence
Finding
This code sends the provided query over HTTP via curl to the configured SearxNG server, which can disclose user-supplied content and possibly local environment usage patterns. Although the module docstring documents the endpoint and general usage, there is no explicit warning, confirmation, or user-facing disclosure that search terms are transmitted to an external or configured service.

Static analysis

No suspicious patterns detected.