Back to skill

Security audit

Indeed Brightdata

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Indeed/Bright Data purpose, but it needs review because one polling script accepts crafted timing options that can execute local shell commands.

Review before installing. Use a narrowly scoped Bright Data key, avoid the optional unpinned npx installer, and do not let untrusted prompts or inputs control script options until --timeout and --interval are strictly validated. Be aware that job searches, company URLs, and fetched results are sent to Bright Data and cached locally under ~/.config/indeed-brightdata.

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

Error
Location
scripts/indeed_poll_and_fetch.sh:52
Finding

Command Injection Through Unvalidated Arithmetic Input

Content
View full analysis
&2; exit 1; } case "$1" in --timeout) TIMEOUT="$2" ;; --interval) INTERVAL="$2" ;; --description) DESCRIPTION="$2" ;; --dataset-type) DATASET_TYPE="$2" ;; esac shift 2 ;; ``` The unvalidated value is subsequently used in an arithmetic comparison: ```bash while [[ "$elapsed" -lt "$TIMEOUT" ]]; do ``` ### Technical Analysis The `--timeout` argument is assigned directly to `TIMEOUT` without verifying that it is a decimal integer. It is subsequently used as an operand in a Bash arithmetic comparison. Bash arithmetic contexts parse operand values as arithmetic expressions rather than inert strings. Arithmetic expressions can recursively resolve variable names and array subscripts, and specially constructed expressions can cause additional shell expansions. Consequently, treating untrusted input as an arithmetic operand may permit command execution rather than merely causing a numeric parsing error. The same validation omission affects `--interval`. Although that value is first passed as a quoted argument to `sleep`, it is also later evaluated in: ```bash elapsed=$((elapsed + INTERVAL)) ``` Strict numeric validation is therefore required for both options. ### Attack Path 1. An attacker supplies or induces the agent to supply a crafted nonnumeric value to `--timeout`. 2. `parse_args` stores the value verbatim in `TIMEOUT`. 3. Execution reaches the loop condition at line 104. 4. Bash interprets the supplied value as part of an arithmetic expression. 5. Malicious expansion embedded in that expression can execute a local co ...[truncated 771 chars]
Remediation
View remediation
maximum )); then echo "Error: ${name} must be an integer between 1 and ${maximum}" >&2 exit 1 fi } case "$1" in --timeout) validate_positive_integer "--timeout" "$2" 3600 TIMEOUT="$2" ;; --interval) validate_positive_integer "--interval" "$2" 300 INTERVAL="$2" ;; esac ``` Additional hardening should include: - Use `10#` when converting validated decimal input to prevent unintended octal interpretation. - Enforce sensible upper bounds to prevent excessive polling or denial of service. - Reject zero and negative values. - Add regression tests containing whitespace, signs, arithmetic operators, variable names, array syntax, and command-substitution syntax. - Avoid placing any untrusted string into Bash arithmetic contexts unless it has first passed a strict decimal-only allowlist. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_lib.sh:36
Finding

Bright Data API Key Exposed Through Process Arguments

Content
View full analysis
``` Although the request uses HTTPS and the header is appropriate for authenticating to Bright Data, placing the secret in the argument vector can make it visible through process-inspection facilities. The exact exposure depends on operating-system process visibility, container boundaries, monitoring software, and whether other local users can inspect the process. The network transmission itself is necessary for the Skill's declared functionality and is sent to the expected provider. The issue is the local delivery mechanism used to provide the header to `curl`, not the use of bearer authentication. ### Attack Path 1. The Skill invokes a search or polling operation. 2. `make_api_request` reads `BRIGHTDATA_API_KEY` from the environment. 3. The function constructs a `curl` argument containing the complete bearer token. 4. While `curl` is running, another local process, monitoring agent, or user with sufficient process-inspection access reads its command-line arguments. 5. The observer extracts and reuses the Bright Data API key. ### Impact Assessment An exposed key may permit unauthorized Bright Data API operations within the permissions and billing limits assigned to that credenti ...[truncated 431 chars]
Remediation
View remediation
"$config_file" if ! response=$(curl --config "$config_file" "${other_curl_args[@]}" "$endpoint"); then rm -f "$config_file" # Handle failure fi rm -f "$config_file" ``` Further hardening should include: - Install a cleanup trap immediately after creating the protected file. - Ensure the temporary directory is not shared insecurely and that the file is owned by the current user. - Never print the API key in diagnostics, debug traces, or HTTP error messages. - Keep `set -x` disabled around credential-handling code. - Use a narrowly scoped Bright Data key with minimum required dataset permissions and spending limits. - Rotate the key if process-monitoring logs may already have captured command lines. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:92
Finding

Unpinned Third-Party Package Execution in Installation Instructions

Content
View full analysis
Remediation
View remediation
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (40)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · .gitignore (reported line 10)May include surrounding context.

text
docs/

# Environment
.env
.env.*

# OS

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes runtime functionality for searching and scraping Indeed via Bright Data. The actual code chunk does not implement any of that behavior; it only installs the skill for supported platforms and checks environment/setup prerequisites. While checking for BRIGHTDATA_API_KEY is consistent with the description, the primary behavior of this code is installation, not Indeed data retrieval. Therefore the supplied code chunk does not accurately represent the declared skill behavior and is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a full Indeed scraping/search skill backed by Bright Data's Web Scraper API. However, this code chunk is explicitly a pure formatting script: it consumes already-produced JSON input and reformats it. It performs no remote access, no Indeed lookup, no API requests, no scraping, and no polling. Its primary purpose is materially different from the declared purpose. While it is related to Indeed data, it represents only a post-processing helper, not the described acquisition/search capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This code chunk is not implementing the advertised Indeed search/scraping behavior. Its primary function is administrative/discovery-oriented: calling Bright Data's dataset listing endpoint, filtering returned dataset definitions for 'Indeed', and optionally persisting dataset IDs to ~/.config/indeed-brightdata/datasets.json. While this may support a larger Indeed scraping workflow, on its own it does not perform the declared user-facing capabilities such as keyword/location search, URL-based extraction, company discovery, or batch data collection. Therefore the code's actual behavior is materially narrower and partially different from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says the skill searches and scrapes Indeed data via Bright Data's API. The supplied code chunk does none of that. It only packages the project into a ZIP file for distribution, copying files and creating an archive. This is a materially different primary purpose from the declared runtime functionality, so this chunk does not accurately represent the described behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 52)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 68)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 92)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 95)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 98)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 101)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 119)May include surrounding context.

md
| `indeed_smart_search.sh` | **Primary job search** — keyword expansion, parallel queries, dedup, caching | ASYNC |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 59)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 79)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 110)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 113)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 116)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 119)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 129)May include surrounding context.

md
| `indeed_format_results.sh` | Format JSON results into summary, full, or CSV | Local |

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/_lib.sh (reported line 351)May include surrounding context.

sh
jq -r --argjson cutoff "$history_cutoff" \
      '.[] | select((.timestamp | fromdateiso8601) <= $cutoff) | .result_file // empty' \
      "$LIB_HISTORY_FILE" 2>/dev/null | while IFS= read -r file; do
      [[ -n "$file" && -f "$file" ]] && rm -f "$file"
    done

    # Remove old entries from history

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 37)May include surrounding context.

md
├── Wants to search by keyword/location?
│   └── indeed_smart_search.sh [ASYNC — 3-8 min]
│       Agent says: "Searching now, this takes a few minutes."
│       If results < 5: auto-expands date range, do NOT ask user
│       Always pipe output through: indeed_format_results.sh --top 5
├── Wants company info?
│   ├── Has Indeed company URL → indeed_company_by_url.sh [SYNC — seconds]

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill is explicitly designed to transmit data and a bearer credential to a third-party service endpoint at api.brightdata.com. While that is expected for the stated purpose, any user-supplied search terms, URLs, or company/job data sent to the external API may expose sensitive research activity or personal data if inputs are not minimized and users are not informed.

Content

Scanner excerpt · SKILL.md (reported line 160)May include surrounding context.

md
All scripts source `scripts/_lib.sh` for shared HTTP and persistence functions. The library:

- Makes requests to a **single endpoint**: `https://api.brightdata.com/datasets/v3`
- Uses **one credential**: `BRIGHTDATA_API_KEY` (sent via `Authorization: Bearer` header)
- Writes **only** to `~/.config/indeed-brightdata/` (see Data Storage above)
- Does not read other environment variables, contact other hosts, or modify files outside its config directory