Back to skill

Security audit

Rent-A-Human-Agent + Bounty Hunter

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with hiring and bounty-scanning, but it has broad activation plus automatic third-party data sharing and undocumented Telegram configuration that users should review before installing.

Install only if you are comfortable giving the skill RentAHuman and xAI API access and with bounty details being sent to xAI for scoring. Review Telegram behavior before running the CLI: notifications are attempted by default, the implemented token and chat lookup differ from the docs, and the helper module is not bundled. Use explicit /rent commands and avoid allowing broad auto-activation for posting jobs, messaging humans, accepting applications, or any paid workflow unless you have a confirmation step in your agent setup.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

other

Warning
Location
bounty_hunter.py:268
Finding
Hardcoded Personal Profile and Bounty Data Transmitted to xAI<![CDATA[ ## Vulnerability Details **File Location**: `bounty_hunter.py:268-300` **Vulnerability Type**: External disclosure of profile attributes and bounty content **Risk Level**: Medium ### Vulnerable Code ```python def grok_score_bounties(bounties): """Send bounties to Grok for AI scoring. Returns [(bounty, score), ...] sorted.""" if not XAI_API_KEY or not bounties: if not XAI_API_KEY: _log("XAI_API_KEY not set — skipping Grok") return None _log(f"Sending {len(bounties)} bounties to Grok (grok-4-1-fast-reasoning)...") # Build compact bounty summaries for the prompt summaries = [] for i, b in enumerate(bounties): summaries.append({ "idx": i, "title": b.get("title", ""), "price": b.get("price", 0), "hours": b.get("estimatedHours", 0), "category": b.get("category", ""), "skills": b.get("skillsNeeded", []), "remote": b.get("location", {}).get("isRemoteAllowed", False), "spots": b.get("spotsAvailable", 1), "desc": (b.get("description", "") or "")[:300], }) prompt = ( "You are a bounty evaluator for a freelance platform. Score each bounty 0-100 " "based on: pay rate, feasibility, location requirements (I'm in northern Ohio, USA) skill match (python, web dev, " "AI, automation, marketing, writing, research, vibe coach, photographer, telegram, psychologist, life coach, mcp, design), remote availability, and description quality.\n\n" "IMPORTANT: These should be REAL JOB POSTINGS where someone pays for work to be done. " "Score < 10 for 'for hire' self-promotions (people advertising their own skills/services, " "résumés, 'hire me' posts). Only score high for actual tasks/gigs with clear deliverables.\n\n" "Flag scams (crypto deposits, upfront payments, suspicious links) with score < 20.\n\n" f"Bounties:\n{json.dumps(summari ...[truncated 2302 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the hardcoded location and skill profile. 2. Obtain profile attributes from explicit, user-controlled configuration. 3. Require informed opt-in before sending bounty data to xAI. 4. Clearly document every field transmitted to the external model. 5. Minimize transmitted data by omitting unnecessary metadata and truncating or redacting sensitive text. 6. Provide deterministic local scoring as the default, with external AI scoring as an optional mode. 7. Define data-retention and privacy expectations for external model processing. 8. Allow users to inspect the generated prompt before transmission when sensitive bounty information may be involved. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bounty_hunter.py:509
Finding
Telegram Delivery Uses Undocumented Credentials and an Unbundled Profile Helper<![CDATA[ ## Vulnerability Details **File Location**: `bounty_hunter.py:509-524` and `bounty_hunter.py:587-598` **Vulnerability Type**: Unsafe notification configuration and unintended outbound disclosure **Risk Level**: Medium ### Vulnerable Code ```python def send_telegram(text): """Send via Telegram bot API (for cron use).""" from telegram_helpers import _load_profile profile = _load_profile() chat_id = profile.get("telegram", {}).get("chat_id") bot_token = os.getenv("KATANA_HTTP_TELEGRAM_BOT_TOKEN", "") if not chat_id or not bot_token: print(text) return requests.post( f"https://api.telegram.org/bot{bot_token}/sendMessage", json={ "chat_id": chat_id, "text": text, "parse_mode": "Markdown", "disable_web_page_preview": True, }, timeout=10, ) ``` ```python force = "--force" in sys.argv skip_tg = "--no-telegram" in sys.argv _log("Bounty scanner starting...") result = scan(hours=140, limit=20, force=force) print() print(result) print() if not skip_tg and "No bounties" not in result and "not set" not in result: send_telegram(result) _log("Sent digest to Telegram") else: _log("Done (not sent to Telegram)") ``` ### Technical Analysis Normal scanner execution attempts Telegram delivery unless the user supplies `--no-telegram`. This makes outbound notification an opt-out behavior even though the documentation describes Telegram as optional. The implementation does not use the documented `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` variables. Instead, it obtains the destination chat from an unbundled `telegram_helpers._load_profile()` function and reads `KATANA_HTTP_TELEGRAM_BOT_TOKEN`. Because `telegram_helpers` is absent from the audited package, its profile-selection behavior and security properties cannot be verified. The Telegram bot token is also embedded in the request URL, as required by Telegram's Bot API design. ...[truncated 1744 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make Telegram delivery opt-in, such as through an explicit `--telegram` flag. 2. Use the documented `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` variables consistently. 3. Require confirmation of the destination chat before the first transmission. 4. Remove the dependency on `telegram_helpers`, or bundle and audit a narrowly scoped implementation. 5. If the helper remains external, import it from an explicitly trusted package and verify its origin. 6. Validate the chat ID format and restrict delivery to an allowlisted destination. 7. Call `raise_for_status()` and log success only after Telegram confirms delivery. 8. Ensure exceptions, HTTP traces, proxies, and monitoring systems redact bot-token-bearing URLs. 9. Avoid transmitting sensitive bounty fields unless the user explicitly enables them. 10. Update the README and Skill documentation to describe the exact configuration and default behavior. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bounty_hunter.py:268
Finding
Untrusted Bounty Content Is Embedded Directly in an AI Instruction Prompt<![CDATA[ ## Vulnerability Details **File Location**: `bounty_hunter.py:268-313` **Vulnerability Type**: Indirect prompt injection and unsafe rendering of model output **Risk Level**: Medium ### Vulnerable Code ```python # Build compact bounty summaries for the prompt summaries = [] for i, b in enumerate(bounties): summaries.append({ "idx": i, "title": b.get("title", ""), "price": b.get("price", 0), "hours": b.get("estimatedHours", 0), "category": b.get("category", ""), "skills": b.get("skillsNeeded", []), "remote": b.get("location", {}).get("isRemoteAllowed", False), "spots": b.get("spotsAvailable", 1), "desc": (b.get("description", "") or "")[:300], }) prompt = ( "You are a bounty evaluator for a freelance platform. Score each bounty 0-100 " "based on: pay rate, feasibility, location requirements (I'm in northern Ohio, USA) skill match (python, web dev, " "AI, automation, marketing, writing, research, vibe coach, photographer, telegram, psychologist, life coach, mcp, design), remote availability, and description quality.\n\n" "IMPORTANT: These should be REAL JOB POSTINGS where someone pays for work to be done. " "Score < 10 for 'for hire' self-promotions (people advertising their own skills/services, " "résumés, 'hire me' posts). Only score high for actual tasks/gigs with clear deliverables.\n\n" "Flag scams (crypto deposits, upfront payments, suspicious links) with score < 20.\n\n" f"Bounties:\n{json.dumps(summaries)}\n\n" "Respond with ONLY a JSON array, no markdown, no explanation:\n" '[{"idx": 0, "score": 90, "reason": "Good pay, skill match"}, ...]' ) try: r = requests.post( "https://api.x.ai/v1/chat/completions", headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"}, json={ "model": "grok-4-1-fast-reasoning", "messages": [{"role": "user", "content": ...[truncated 3642 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every bounty field as untrusted data and clearly delimit it from system instructions. 2. Use separate system and user messages, with the system message explicitly prohibiting obedience to instructions found in bounty content. 3. Prefer schema-constrained or structured model output when supported by the API. 4. Validate that the response is an array of objects with unique, in-range integer indices. 5. Require scores to be finite numeric values between 0 and 100. 6. Limit reasons to a conservative character count and reject unexpected control characters or markup. 7. Escape Telegram Markdown metacharacters in titles, names, reasons, and all other untrusted fields. 8. Reapply deterministic scam and self-promotion checks after AI scoring so model output cannot bypass local controls. 9. Detect suspicious instruction-like phrases in bounty content and either exclude those records from AI scoring or flag them for manual review. 10. Preserve a non-AI heuristic score and display discrepancies between deterministic and model-generated rankings. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (20)

YARA rule 'agent_skill_credential_exfiltration_webhook': AI agent skill credential harvesting followed by webhook or external exfiltration [agent_skills]

Critical
Category
YARA Match
Content
/skills/rent/scripts/bounty_hunter.py -> project root
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent
SCRIPT_DIR = Path(__file__).parent

# Skill directory is 2 levels up from this script
# .claude/skills/rent/scripts/bounty_hunter.py -> .claude/skills/rent/
PROJECT_DIR = Path(__file__).parent.parent

# Load .env from project root
load_dotenv(PROJECT_ROOT / ".env")

RENTAHUMAN_API_KEY = os.getenv("RENTAHUMAN_API_KEY", "")
XAI_API_KEY = os.getenv("XAI_API_KEY", "")
RENTAHUMAN_BASE = "https://rentahuman.ai/api"
RENTAHUMAN_WEB = "https://rentahuman.ai"
CACHE_DIR = PROJECT_DIR / "cache"
CACHE_DIR.mkdir(exist_ok=True)
CACHE_FILE = CACHE_DIR / "bounties_cache.json"
CACHE_TXT_FILE = CACHE_DIR / "bounties_ranked.txt"
CACHE_TTL_HOURS = 12
CACHE_VERSION = 2  # Bump to invalidate old caches (v1 had unfiltered for-hire ads)

# Skills you can actually do — bounties matching these score higher
MY_SKILLS = [
    "web development", "python", "javascript", "react", "node",
    "automation",
Confidence
85% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

YARA rule 'ransomware_behavior': Ransomware-like patterns (mass encryption, ransom notes) [malware]

Critical
Category
YARA Match
Content
ranked.txt"
CACHE_TTL_HOURS = 12
CACHE_VERSION = 2  # Bump to invalidate old caches (v1 had unfiltered for-hire ads)

# Skills you can actually do — bounties matching these score higher
MY_SKILLS = [
    "web development", "python", "javascript", "react", "node",
    "automation", "ai", "swe", "full stack", "marketing",
    "research", "writing", "data entry", "design",
]

SCAM_SIGNALS = [
    "send money", "send eth", "send btc", "send crypto",
    "wallet:", "0x", "deposit first", "return to your",
    "get paid to register", "sign up and get", "2.5x",
    "dm me", "whatsapp", "join our telegram",
]

# "For hire" self-promotions — these are people advertising themselves, not posting jobs
FOR_HIRE_SIGNALS = [
    "my name is", "i am a ", "i'm a ", "hire me", "available for",
    "looking for work", "looking for opportunities", "my portfolio",
    "my experience", "years of experience", "i specialize in",
    "i offer", "my services", "freelancer with", "developer with",
    "i can
Confidence
80% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tainted flow: 'XAI_API_KEY' from os.getenv (line 42, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
)

    try:
        r = requests.post(
            "https://api.x.ai/v1/chat/completions",
            headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"},
            json={
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'bot_token' from os.getenv (line 514, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if not chat_id or not bot_token:
        print(text)
        return
    requests.post(
        f"https://api.telegram.org/bot{bot_token}/sendMessage",
        json={
            "chat_id": chat_id,
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Vague Triggers

High
Confidence
98% confidence
Finding
The trigger list includes broad, everyday phrases such as 'hire someone,' 'human assistant,' and 'errands,' which can cause the skill to activate in situations far beyond the user's intent. Because this skill connects to external services and can initiate hiring, posting, and messaging workflows, unintended activation could expose user data or prompt consequential actions on third-party platforms.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
---
name: rent
triggers: "hire a human, rent a human, delegate to human, find a freelancer, post a bounty, hire someone, human assistant, errands, rentahuman, bounty"
description: "Delegate tasks to real humans via RentAHuman.ai — search skills, post bounties, manage conversations, and run AI-scored opportunity scans."
---

# Rent-A-Human Bounty Hunter

Scans RentAHuman.ai bounties via MCP + API. Uses Grok AI to filter spam,
score opportunities by location, skills, and ease of completion, and sends
top results to Telegram.

🔍 Scan Bounties - Find and score job opportunities based on your location and sk
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Vague Triggers

High
Confidence
97% confidence
Finding
The auto-activation rule 'when the user wants to hire a person, post a job, or delegate a task' is ambiguous and broad enough to match many normal conversations. In this context, accidental invocation is especially risky because the skill can access external APIs, browse humans, post bounties, and send messages, creating opportunities for privacy leaks or unintended real-world transactions.

Credential Access

High
Category
Privilege Escalation
Content
# .claude/skills/rent/scripts/bounty_hunter.py -> .claude/skills/rent/
PROJECT_DIR = Path(__file__).parent.parent

# Load .env from project root
load_dotenv(PROJECT_ROOT / ".env")

RENTAHUMAN_API_KEY = os.getenv("RENTAHUMAN_API_KEY", "")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
PROJECT_DIR = Path(__file__).parent.parent

# Load .env from project root
load_dotenv(PROJECT_ROOT / ".env")

RENTAHUMAN_API_KEY = os.getenv("RENTAHUMAN_API_KEY", "")
XAI_API_KEY = os.getenv("XAI_API_KEY", "")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README advertises live scanning via MCP/API, Grok-based scoring, and Telegram delivery, but does not clearly warn users what data may be transmitted to third parties. In an agent setting, users may not realize prompts, job data, preferences, or derived ranking information could be shared with external providers, creating privacy and compliance risks.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The invocation examples are very broad and action-oriented, which increases the chance the skill is triggered in situations the user did not specifically intend. Because the skill can query external services and optionally send results to Telegram, accidental activation could lead to unnecessary external requests and unintended data disclosure or notification spam.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill description states that it scans bounties via MCP and API, uses Grok AI for scoring, and sends results to Telegram, but it does not clearly warn users that their prompts, job details, skills, or other data may be transmitted to multiple third-party services. This omission undermines informed consent and increases the chance that sensitive personal or business information will be shared externally without the user realizing it.

External Transmission

Medium
Category
Data Exfiltration
Content
)

    try:
        r = requests.post(
            "https://api.x.ai/v1/chat/completions",
            headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"},
            json={
Confidence
70% confidence
Finding
This duplicate finding points to the same x.ai outbound request. The risk is not secret exfiltration but third-party transmission of potentially sensitive bounty content to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
)

    try:
        r = requests.post(
            "https://api.x.ai/v1/chat/completions",
            headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"},
            json={
Confidence
80% confidence
Finding
This duplicate finding points to the same x.ai outbound request. The risk is not secret exfiltration but third-party transmission of potentially sensitive bounty content to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
try:
        r = requests.post(
            "https://api.x.ai/v1/chat/completions",
            headers={"Authorization": f"Bearer {XAI_API_KEY}", "Content-Type": "application/json"},
            json={
                "model": "grok-4-1-fast-reasoning",
Confidence
72% confidence
Finding
The hardcoded x.ai endpoint confirms that bounty data is being sent to an external third-party AI provider. In context this is intentional functionality, but it still represents real data egress that may be unacceptable in some environments without disclosure and consent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script automatically transmits scan results to Telegram using profile-derived chat data and a bot token, with opt-out only via a CLI flag. In an agent-skill context, automatic external transmission of aggregated job data and profile-linked destination information can create unintended privacy and data-sharing risk, especially if users are unaware that content will be sent off-platform.

External Transmission

Medium
Category
Data Exfiltration
Content
if not chat_id or not bot_token:
        print(text)
        return
    requests.post(
        f"https://api.telegram.org/bot{bot_token}/sendMessage",
        json={
            "chat_id": chat_id,
Confidence
80% confidence
Finding
The script transmits formatted digests to Telegram, an external service, using a chat identifier loaded from a profile helper. In a skill/agent setting, automatic outbound messaging can leak operational data or user-derived context if the configured destination is wrong, compromised, or unexpected.

External Transmission

Medium
Category
Data Exfiltration
Content
print(text)
        return
    requests.post(
        f"https://api.telegram.org/bot{bot_token}/sendMessage",
        json={
            "chat_id": chat_id,
            "text": text,
Confidence
77% confidence
Finding
The hardcoded Telegram API endpoint indicates intentional off-host transmission of digest content. This is more security-relevant in an agent skill because users may not expect autonomous external messaging during scans or cron execution.

Intent-Code Divergence

Low
Confidence
84% confidence
Finding
The module docstring presents the script as a bounty scanner focused on pulling, scoring, filtering, and sending bounty picks. However, the implemented CLI includes a separate '--humans'/'--rent' path that invokes 'list_humans()' to enumerate people for hire, which is a distinct function not reflected in the stated module purpose.

Context-Inappropriate Capability

Low
Confidence
75% confidence
Finding
With no manifest available, the only stated purpose comes from the file-level documentation, which frames this as a bounty scanner for jobs. The 'list_humans' feature reaches into another helper to retrieve available humans for hire, a materially different capability from scanning and ranking bounties.