Back to skill

Security audit

Multi-Platform Bounty Scanner

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its package metadata can cause an unrelated npm package named `gh` to be installed instead of simply requiring the GitHub CLI.

Review this before installing. The scanner is not a hidden backdoor, but the package should remove the `gh` npm peer dependency and document installation of the official GitHub CLI instead. Also expect local scan history under `~/.bounty-scanner`, GitHub network requests, and only GitHub scanning despite broader marketing claims.

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 (2)

T08 · Insecure Dependencies

Warning
Location
package.json:25
Finding
Incorrect and Unbounded npm Peer Dependency Creates Supply-Chain Risk## Vulnerability Details **File Location**: `package.json:25-27` **Vulnerability Type**: Insecure third-party dependency declaration **Risk Level**: Medium ### Vulnerable Code ```json "peerDependencies": { "gh": ">=2.0.0" } ``` ### Technical Analysis The application requires the official GitHub CLI system executable named `gh`, which it invokes through `execSync`. However, `package.json` represents this requirement as an npm peer dependency. An npm package named `gh` is not an equivalent declaration of the official system-level GitHub CLI. Modern npm versions can automatically resolve and install peer dependencies. Consequently, installing this project may retrieve registry code that is unnecessary for the scanner's documented operation. The version range is also unbounded (`>=2.0.0`), allowing any later version to satisfy the dependency. This provides no upper compatibility boundary or immutable integrity guarantee. If the registry package or a future release is malicious or compromised, its installation or lifecycle behavior could execute with the privileges of the user running npm. ### Attack Path 1. A user installs the skill through npm or a workflow that automatically resolves peer dependencies. 2. npm interprets `gh` as an npm registry package rather than as a requirement for the official GitHub CLI executable. 3. npm retrieves a version satisfying the unbounded `>=2.0.0` constraint. 4. If the resolved package or version has been compromised, attacker-controlled lifecycle or runtime code executes during installation or subsequent use. 5. That code runs with the installing user's privileges and can access files, credentials, environment variables, and network resources available to that user. ### Impact Assessment Exploitation depends on a malicious or compromised dependency being resolved. If that occurs, arbitrary code could execute with the privileges of the user installing the skill. The potential sc ...[truncated 300 chars]
Remediation
## Remediation Suggestions 1. Remove `gh` from `peerDependencies`; an npm dependency is not the correct mechanism for requiring the official GitHub CLI. 2. Document installation of the official GitHub CLI separately, including trusted vendor installation sources. 3. At startup, validate that `gh` exists and fail safely with a clear message if it is unavailable. 4. Optionally invoke `gh --version` and enforce a supported version range. 5. If the implementation is changed to use a JavaScript GitHub API client, select a vetted package, pin compatible versions, commit a lockfile, and use npm integrity metadata and dependency scanning. 6. Disable unnecessary dependency lifecycle scripts in sensitive installation environments where operationally feasible.

T09 · Insecure Skill Coding Practices

Note
Location
scanner.js:179
Finding
Remote GitHub Issue Titles Are Printed Without Terminal Control-Sequence Neutralization## Vulnerability Details **File Location**: `scanner.js:24-25`, `scanner.js:31-39`, `scanner.js:179-183`, and `scanner.js:226` **Vulnerability Type**: Unsafe terminal rendering of attacker-controlled remote content **Risk Level**: Low ### Vulnerable Code Remote GitHub content is parsed and retained without sanitization: ```js const result = execSync(cmd, { encoding: 'utf8' }); const issues = JSON.parse(result); return issues .filter(issue => { const created = new Date(issue.createdAt); const daysSince = (Date.now() - created) / (1000 * 60 * 60 * 24); return daysSince < 7; // Only last 7 days }) .map(issue => ({ id: `github-${issue.repository.nameWithOwner}-${issue.url.split('/').pop()}`, platform: 'github', title: issue.title, ``` The remote title is then directly incorporated into terminal output: ```js for (const bounty of bounties) { output += `📌 ${bounty.title}\n`; output += ` Platform: ${bounty.platform}\n`; output += ` Reward: ${bounty.reward}\n`; output += ` Tech: ${bounty.techStack.join(', ') || 'Unknown'}\n`; output += ` URL: ${bounty.url}\n`; output += `\n`; } ``` The resulting string is printed to the active terminal: ```js console.log(output); ``` ### Technical Analysis GitHub issue titles are remotely controlled data. The scanner retrieves matching public issues through the GitHub CLI, parses their titles, and writes those titles directly to standard output without removing ANSI escape sequences or C0/C1 control characters. Interactive terminals may interpret embedded control sequences rather than displaying them as ordinary text. Depending on terminal capabilities and configuration, crafted content can clear or overwrite visible output, move the cursor, create deceptive hyperlinks, change window titles, or trigger terminal-specific clipboard operations. JSON serialization is not the vulnerable operation in th ...[truncated 1470 chars]
Remediation
## Remediation Suggestions 1. Treat every field obtained from GitHub as untrusted, including titles, repository names, URLs, labels, and descriptions. 2. Before text-mode terminal rendering, remove ANSI escape sequences and unsafe C0/C1 control characters while preserving ordinary line formatting where required. 3. Use a maintained terminal-sanitization library or a carefully reviewed sanitizer rather than an incomplete ad hoc expression. 4. Consider replacing control characters with visible escaped forms so users can recognize that the source contained unusual data. 5. Keep terminal sanitization separate from JSON output. Preserve raw values only where JSON serialization safely escapes them and where downstream consumers are expected to handle untrusted data. 6. Add automated tests containing ANSI color sequences, OSC hyperlinks, cursor-control sequences, newline injection, and terminal clipboard sequences.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Session Persistence

Medium
Category
Rogue Agent
Content
## Configuration

Create `~/.bounty-scanner/config.json`:

```json
{
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
## Configuration

Create `~/.bounty-scanner/config.json`:

```json
{
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The module header states this is a "Multi-Platform Bounty Scanner" that scans "50+ bounty platforms for new opportunities," but the implemented platform list only contains one functional scanner (GitHub) while Code4rena and Immunefi explicitly return empty mock results. This is an active contradiction between the code documentation and actual behavior, not merely omitted detail.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The markdown describes sending notifications via Telegram and storing bounty data in a local database, both of which can affect user privacy or system data. The document does not include any warning or disclosure about what data is transmitted or retained.

Missing User Warnings

Low
Confidence
85% confidence
Finding
This is a markdown file, so missing-warning findings apply to omitted disclosures about behaviors affecting privacy, data, or system integrity. The document instructs users to schedule recurring scans and create a local config, and later states the scanner tracks seen bounties, but it does not explicitly warn that the skill will make repeated outbound requests and maintain local state.

Missing User Warnings

Low
Confidence
84% confidence
Finding
This code accesses user-local data at ~/.bounty-scanner/config.json, but there is no comment, docstring, or user-facing message explaining that the skill reads configuration from the home directory. For a code file, local file access affecting user data should have some visible disclosure unless already documented elsewhere in the skill.

Missing User Warnings

Low
Confidence
91% confidence
Finding
The function creates ~/.bounty-scanner/seen.json and writes persistent state to disk, but there is no prior warning, prompt, or inline documentation disclosing that the tool stores scan history locally. This is a file-write operation, which falls under the missing user warning criteria for code files.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scanner.js:21