Back to skill

Security audit

Web Search Instant 1.1.0

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward DuckDuckGo search helper, but users should avoid sensitive queries and note a few shell-script hygiene issues.

Install only if you are comfortable sending search terms to DuckDuckGo. Do not use it for secrets, private internal project names, credentials, or sensitive personal data; prefer narrowing the trigger rules and remove the npm jq installation suggestion if maintaining the skill.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
web-search.sh:165
Finding
Untrusted API Content Is Interpreted as Terminal Escape Sequences<![CDATA[ ## Vulnerability Details **File Location**: `web-search.sh:165-189`, with vulnerable output sinks at `web-search.sh:225`, `web-search.sh:252`, `web-search.sh:278`, and `web-search.sh:318` **Vulnerability Type**: Terminal control-sequence injection through unsafe `echo -e` usage **Risk Level**: Medium ### Vulnerable Code ```bash # Parse fields controlled by the remote API response ANSWER=$(echo "$RESPONSE" | jq -r '.Answer // empty' | tr -d '\r\n') ABSTRACT=$(echo "$RESPONSE" | jq -r '.Abstract // empty' | tr -d '\r\n') DEFINITION=$(echo "$RESPONSE" | jq -r '.Definition // empty' | tr -d '\r\n') RELATED_TOPICS=$(echo "$RESPONSE" | jq -r '.RelatedTopics[]?.Text // empty' 2>/dev/null | head -5) # Later output sinks echo -e " $ANSWER" echo -e " $ABSTRACT" echo -e " $DEFINITION" echo "$RELATED_TOPICS" | while read -r topic; do if [ -n "$topic" ] && [ "$topic" != "" ]; then topic_clean=$(echo "$topic" | sed -E 's/<a[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>/\2 (\1)/g' | sed 's/<[^>]*>//g') if [ "$OUTPUT_FORMAT" = "markdown" ]; then echo "- $topic_clean" else echo -e " • $topic_clean" fi fi done | head -n "$MAX_RELATED" ``` ### Technical Analysis The script treats fields returned by the DuckDuckGo API as trusted terminal text. Although some fields have carriage returns and line feeds removed, this does not remove other control characters. Moreover, `echo -e` interprets backslash escape notation contained in its arguments. Consequently, a response containing an actual escape character or text such as `\033]...` can cause the terminal to interpret the response as a control sequence rather than display it as inert text. Removing HTML tags from related topics does not mitigate terminal escape-sequence injection. Potential terminal-dependent effects include: - Rewriting or hiding displayed output. - Forging status messages or result boundaries. - Changing terminal titles or hyperlinks. - Trigg ...[truncated 1644 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never use `echo -e` for untrusted or remotely supplied values. Print data literally: ```bash printf ' %s\n' "$ANSWER" printf ' %s\n' "$ABSTRACT" printf ' %s\n' "$DEFINITION" printf ' • %s\n' "$topic_clean" ``` 2. Apply an explicit control-character policy before printing remote data. For terminal output, remove C0 and C1 controls other than any deliberately permitted whitespace: ```bash sanitize_terminal_text() { LC_ALL=C tr -d '\000-\010\013\014\016-\037\177' } ``` 3. Keep ANSI formatting in constant format strings only: ```bash printf '%b %s%b\n' "$GREEN" "$ANSWER" "$NC" ``` 4. Apply the same sanitization to all remote fields, including headings, source names, URLs, abstracts, definitions, answers, and related topics. 5. Add regression tests containing literal ESC characters and strings such as `\033[2J`, verifying that they are displayed inertly or removed. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:166
Finding
Documentation Recommends an Unpinned Global npm Package as jq<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:166-170` **Vulnerability Type**: Unsafe third-party dependency installation guidance **Risk Level**: Medium ### Vulnerable Code ```bash # Ubuntu/Debian sudo apt-get install jq # macOS brew install jq # Via package managers npm install -g jq ``` ### Technical Analysis The Skill recommends `npm install -g jq` as an alternative way to obtain the JSON processor. An npm package named `jq` is not necessarily the same component, distribution channel, or executable as the standard native `jq` utility provided by established operating-system package repositories. The command has two material supply-chain weaknesses: - No package version or integrity value is pinned. - Global npm installation may execute package lifecycle scripts and modify the user's global executable environment. The effective package contents can change after this Skill has been reviewed. Users may also reasonably interpret the instruction as an official installation method for the native `jq` binary even though npm package naming alone does not establish that provenance. ### Attack Path 1. A user encounters the documented "`jq` not found" condition. 2. The user follows the Skill's npm recommendation. 3. npm resolves the mutable package currently published under the name `jq`. 4. npm downloads the package and its transitive dependencies. 5. Any permitted install lifecycle scripts execute with the privileges of the invoking user. 6. The package installs or modifies files in the global npm environment. A malicious or compromised package could therefore execute code, read user-accessible data, or replace globally resolved command-line tools. If a user unnecessarily runs the npm command with elevated privileges, the potential scope would increase, although the documented command itself does not include `sudo`. ### Impact Assessment The package receives the ordinary privileges of the user running npm and can potentially access tha ...[truncated 367 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the following recommendation entirely: ```bash npm install -g jq ``` 2. Recommend only verified distribution channels for the native `jq` utility, such as the operating system's official package repository. 3. Use explicit package-manager commands appropriate to each supported platform and advise users to verify repository provenance. 4. If distributing a standalone binary is necessary, specify: - The official upstream release URL. - An exact version. - A cryptographic checksum or signature-verification procedure. - The expected executable name and version output. 5. Avoid global language-registry installations for unrelated native utilities, especially when package names can be confused with established system tools. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
test-new-features.sh:143
Finding
Predictable Temporary File Allows Symlink-Based File Clobbering<![CDATA[ ## Vulnerability Details **File Location**: `test-new-features.sh:143-158` **Vulnerability Type**: Insecure predictable temporary file creation **Risk Level**: Medium ### Vulnerable Code ```bash # Test 10: Output to file (via redirection) echo -e "${BLUE}Test 10: Output to file${NC}" TEST_OUTPUT_FILE="/tmp/web-search-test-$$" $TOOL --format plain "test" > "$TEST_OUTPUT_FILE" 2>&1 if [ -f "$TEST_OUTPUT_FILE" ] && [ -s "$TEST_OUTPUT_FILE" ]; then CONTENT=$(cat "$TEST_OUTPUT_FILE") if [ -n "$CONTENT" ]; then echo -e "${GREEN}✓ PASS${NC} Output successfully written to file" PASSED=$((PASSED + 1)) rm -f "$TEST_OUTPUT_FILE" else echo -e "${RED}✗ FAIL${NC} File is empty" FAILED=$((FAILED + 1)) rm -f "$TEST_OUTPUT_FILE" fi else echo -e "${RED}✗ FAIL${NC} File not created" FAILED=$((FAILED + 1)) fi ``` ### Technical Analysis The test builds a temporary pathname from the process ID and places it in the shared `/tmp` directory. The shell then opens that pathname using normal output redirection. The pathname is predictable and is not created atomically with exclusive semantics. On systems where another local user can create entries in `/tmp`, an attacker can pre-create the expected path as a symbolic link. Shell redirection follows the symbolic link and opens the link target with truncation before `web-search.sh` executes. The later checks with `-f` and `-s` happen only after the unsafe open and cannot prevent the overwrite. The cleanup operation may remove the attacker's link, but it does not restore the truncated target. ### Attack Path 1. A local attacker predicts or sprays likely process-ID-based names matching `/tmp/web-search-test-<PID>`. 2. The attacker creates one of those names as a symbolic link to a file writable by the victim. 3. The victim runs `test-new-features.sh`. 4. The shell evaluates: ```bash > "$TEST_OUTPUT_FILE" ``` 5. The shell follows the pre-existing symbolic ...[truncated 927 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the temporary file atomically with `mktemp`: ```bash TEST_OUTPUT_FILE=$(mktemp "${TMPDIR:-/tmp}/web-search-test.XXXXXX") || { echo "Failed to create temporary file" >&2 exit 1 } ``` 2. Register cleanup immediately so the file is removed on normal exit, errors, or signals: ```bash trap 'rm -f -- "$TEST_OUTPUT_FILE"' EXIT HUP INT TERM ``` 3. Keep the pathname quoted and use `--` for cleanup commands: ```bash "$TOOL" --format plain "test" >"$TEST_OUTPUT_FILE" 2>&1 ``` 4. Do not run the test suite with elevated privileges. 5. Where temporary files are unnecessary, capture output directly into a shell variable or use a private temporary directory created with `mktemp -d`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
This second mismatch finding points to the same core issue: the skill is presented as a simple web search interface, but operational details suggest additional filesystem and execution behaviors outside that stated purpose. When a skill fronts a local executable instead of transparently implementing the API interaction, the reviewed surface and the executed surface diverge, increasing the chance of abuse or policy bypass.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This second mismatch finding points to the same core issue: the skill is presented as a simple web search interface, but operational details suggest additional filesystem and execution behaviors outside that stated purpose. When a skill fronts a local executable instead of transparently implementing the API interaction, the reviewed surface and the executed surface diverge, increasing the chance of abuse or policy bypass.

External Transmission

Medium
Category
Data Exfiltration
Content
## API Details

- **Endpoint**: `https://api.duckduckgo.com/`
- **Parameters**:
  - `q` - Search query (URL-encoded)
  - `format=json` - JSON response
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Some abstracts have Unicode issues in basic parsing (non-ASCII characters garbled).
Install `jq` for cleaner output:
```bash
sudo apt-get install jq  # Ubuntu/Debian
brew install jq          # macOS
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Some abstracts have Unicode issues in basic parsing (non-ASCII characters garbled).
Install `jq` for cleaner output:
```bash
sudo apt-get install jq  # Ubuntu/Debian
brew install jq          # macOS
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill documentation describes use of shell and network capabilities but does not declare any explicit tool scope such as permissions or allowed-tools. In an agent environment, undeclared capabilities reduce policy enforcement and reviewability, making it easier for a seemingly simple search skill to execute local commands or make outbound requests beyond what operators expect.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are very broad, including common language like 'what is' and 'how to', which can cause the skill to activate in situations far beyond intended web search usage. Over-invocation increases exposure to network and shell actions, can leak user context to external services, and may override more appropriate safer skills.

Missing User Warnings

Low
Confidence
85% confidence
Finding
This markdown file documents a web search tool that sends the user's query to the DuckDuckGo Instant Answer API, which is a network operation involving user-provided data. The description explains the endpoint and parameters but does not warn users that their queries will be sent to a third-party service.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This shell test script repeatedly invokes `./web-search.sh` with live search queries, which likely triggers network/HTTP requests. While the script prints test names and pass/fail output, it does not disclose that running the tests may send queries off-host, and there is no comment or prompt warning the user about that behavior.

Missing User Warnings

Low
Confidence
92% confidence
Finding
The script sends the user's search query to DuckDuckGo over the network, but it does not provide an explicit user-facing privacy warning at the point of transmission. This can expose sensitive user-entered data if the tool is used with private, internal, or confidential queries, especially in an agent setting where users may not realize their input leaves the local environment.

Static analysis

No suspicious patterns detected.