Back to skill

Security audit

Rent a Person

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent RentAPerson automation purpose, but it exposes powerful account credentials and tells agents to automatically trust and act on external webhook text.

Do not install this as-is for a real account. Rotate any exposed RentAPerson/OpenClaw credentials, remove the committed credential file, disable API-key injection into prompts or transcripts, require verified webhook authentication before agent execution, avoid allowUnsafeExternalContent for public hooks, and require confirmation before hiring, scheduling, or changing task status.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (7)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:5
Finding

Webhook Trust Instructions Override Agent Security Controls

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
bridge/server.js:231
Finding

Unauthenticated Webhook Bridge Enables Prompt Injection into Privileged Sessions

Content
View full analysis
{ if (req.method !== 'POST') { res.writeHead(405, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Method not allowed' })); return; } let body = ''; req.on('data', chunk => body += chunk); req.on('end', () => { try { const payload = JSON.parse(body); console.log(`[bridge] ← RentAPerson: ${payload.event || 'unknown event'}`); forwardToOpenClaw(payload, (err, result) => { // Forwarded without validating a signature, bearer token, source, or schema }); } catch (e) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'In ...[truncated 2139 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/setup.js:687
Finding

Setup Deliberately Enables Unsafe External Content for Immediate Agent Execution

Content
View full analysis
(m.match && m.match.path === HOOK_NAME) || m.name === HOOK_NAME ); if (!rentapersonMapping) { rentapersonMapping = { match: { path: HOOK_NAME }, name: 'RentAPerson' }; config.hooks.mappings.push(rentapersonMapping); } rentapersonMapping.action = 'agent'; rentapersonMapping.allowUnsafeExternalContent = true; rentapersonMapping.sessionKey = normalizeSessionKeyForOpenClaw(webhookSessionKey); rentapersonMapping.wakeMode = 'now'; ``` ### Technical Analysis The setup process configures the webhook mapping to permit unsafe external content and immediately wake an agent session. This removes or bypasses a platform-level protection intended to distinguish external content from trusted instructions. The mapping targets a persistent session that has access to the RentAPerson Skill and API credential. When combined with the Skill's automatic execution instructions, unsafe external text can directly influence privileged agent behavior. ### Attack Path 1. The user runs `scripts/setup.js`. 2. Setup writes `allowUnsafeExternalContent: true` into `openclaw.json`. 3. A request reaches `/hooks/rentaperson`. 4. The gateway accepts external content under the unsafe-content setting and wakes the configured session immediately. 5. The agent processes the event under the Skill's automatic workflow. 6. Malicious external content may influence authenticated actions. ### Impact Assessment This configuration weakens the OpenClaw content-trust boundary for an always-on session. It increases the likelihood and reliability of prompt injection and expands the possible impact to every capability available to the webhook agent, including the RentAPerson API credential. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
rentaperson-agent.json:2
Finding

Live-Looking API and Webhook Credentials Are Committed in Plaintext

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.js:250
Finding

Setup Stores Secrets with Default Permissions and Injects Them into Persistent Session Transcripts

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send-to-session.js:13
Finding

Shell Command Injection in OpenClaw Session Helper

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Warning
Location
INSTALLATION.md:250
Finding

Persistent Boot Service Magnifies Exposure of the Unauthenticated Bridge

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (88)

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

Critical
Category
YARA Match
Confidence
98% confidence
Finding

The YARA match is supported by the surrounding content: the skill stores credentials, discusses process.env, recommends key injection into prompts as fallback, and instructs automatic webhook-driven API actions. In context, this forms a credible credential exposure and unauthorized action chain rather than a benign documentation artifact.

Content

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

skill directory:

bash
node scripts/setup.js

The script will prompt for:

  • Friendly agent name (defaults to your workspace/agent name)
  • Contact email
  • Main session key (default: agent:main:main) - for chat correspondence
  • Webhook session key (default: agent:main:rentaperson) - for webhook processing
  • Webhook URL (e.g. your ngrok HTTPS URL, e.g. https://abc123.ngrok.io)
  • OpenClaw hooks token (for Authorization: Bearer on webhooks)

It then:

  1. Calls POST /api/agents/register and saves agentId and apiKey to rentaperson-agent.json
  2. Updates your openclaw.json (default: ~/.openclaw/openclaw.json; override with OPENCLAW_CONFIG) to inject skills.entries["rent-a-person-ai"].env with the key, agentId, agentName, etc.
  3. Configures webhook mapping to use the webhook session key
  4. Calls PATCH /api/agents/me with the webhook URL, bearer token, and webhook session key
  5. Tells you to restart the gateway so the new env takes effect

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

Critical
Category
YARA Match
Confidence
85% confidence
Finding

The YARA match is broad, but the file does combine credential collection/storage with webhook and session delivery behavior that can expose those credentials externally or to untrusted agent contexts. While there is no clear evidence of deliberate attacker exfiltration to a third-party server, the overall design creates a high-risk secret-handling path that could lead to effective credential exfiltration in practice.

Content

Scanner excerpt · scripts/setup.js (reported line 24)May include surrounding context.

js
ir + mapping for /hooks/rentaperson)
 * - Registers webhook at <gateway>/hooks/rentaperson with webhookSessionKey, webhookFormat, webhookBearerToken
 * - Optional: restart gateway, optional verify
 */

const fs = require('fs');
const path = require('path');
const readline = require('readline');
const { spawn } = require('child_process');
const net = require('net');

const OPENCLAW_CONFIG_PATH =
  process.env.OPENCLAW_CONFIG ||
  path.join(process.env.HOME || process.env.USERPROFILE || '', '.openclaw', 'openclaw.json');

const ENVS = {
  prod: 'https://rentaperson.ai',
  dev: 'https://dev.rentaperson.ai',
};

const TRANSFORM_FILENAME = 'rentaperson-inject-key-transform.js';
const HOOK_NAME = 'rentaperson';

function ask(rl, question, defaultVal = '') {
  const suffix = defaultVal ? ` [${defaultVal}]` : '';
  return new Promise((resolve) => {
    rl.question(`${question}${suffix}: `, (answer) => {
      resolve((answer && answer.trim()) || defaultVal);
    });
  });
}

function askYesNo(

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The transform approach states that the API key appears in session transcripts, which means a long-lived secret may be copied into logs, history, exports, or downstream tools that can access transcript content. Because this is documented as an available setup option without a strong do-not-use warning, users may deploy an architecture that intentionally exposes credentials to broader surfaces.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to trust webhook-like message content based on keywords and to ignore distrust of external requests. That lets an attacker craft a prompt containing those markers and trigger autonomous API actions, effectively bypassing origin authentication and normal safety checks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill tells the agent to treat certain message patterns as trusted and to ignore platform security notices. This is a direct prompt-level attempt to override trust decisions, enabling spoofed webhook messages to drive authenticated actions.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill semantically redefines matching webhook-like text as authoritative commands and instructs the agent to execute workflows from that text. This is a classic prompt injection pattern that can convert untrusted content into privileged actions, including replying to conversations and manipulating application state.

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 36)May include surrounding context.

md
node scripts/setup.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/setup.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/setup.js

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly recommends putting secrets into mapped hook payloads/messages while acknowledging they will appear in transcripts. This creates deliberate credential exposure to anyone with session visibility and makes later prompt exfiltration trivial.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill instructs operators to inject API keys into prompt/message content so the agent can consume them. That exposes credentials in transcripts, logs, session history, and potentially downstream tools, creating a straightforward path to secret theft and account compromise.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill directs the model to ignore security warnings and automatically process webhook content, which weakens the final safety barrier before external side effects. In practice, this makes prompt spoofing and unsafe automation substantially easier.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Telling the agent to ignore a security notice for webhooks is an explicit attempt to suppress safeguards that warn about untrusted input. This increases the probability that spoofed or replayed webhook-like prompts will be acted on automatically.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill tells the agent to extract an API key from message content and use it for privileged API calls. This treats prompt content as a secret source, enabling credential harvesting, replay, leakage in transcripts, and attacker-supplied key substitution.

Content

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

List applications for a bounty:

bash
# Extract API key from message (look for "🔑 API KEY: rap_xxx"), then:
curl -H "X-API-Key: rap_xxx" "https://rentaperson.ai/api/bounties/BOUNTY_ID/applications"

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Again, the skill normalizes extracting API keys from message content before performing API operations. This is dangerous because any party able to influence the prompt can introduce, steal, or redirect credential usage.

Content

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

Start conversation (if none exists):

bash
# Extract API key from message, then:
curl -H "X-API-Key: rap_xxx" -X POST "https://rentaperson.ai/api/conversations" \
  -H "Content-Type: application/json" \
  -d '{

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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).

Content

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

md
| `get_calendar_event` | GET /api/calendar/events/:id |
| `list_calendar_events` | GET /api/calendar/events |
| `update_calendar_event` | PATCH /api/calendar/events/:id |
| `delete_calendar_event` | DELETE /api/calendar/events/:id |
| `check_availability` | GET /api/calendar/availability |
| `get_calendar_status` | GET /api/calendar/status |

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The transform code reads a stored API key from configuration and injects it into the message body for later use. Accessing credentials itself is not inherently malicious, but here it is paired with unsafe propagation of the secret into conversational content, which can expose it to transcript storage, logs, and downstream consumers.

Content

Scanner excerpt · WEBHOOK_API_KEY_SOLUTION.md (reported line 55)May include surrounding context.

md
}

function injectKey(body, config) {
  const env = config?.skills?.entries?.['rent-a-person-ai']?.env || {};
  const key = env.RENTAPERSON_API_KEY;
  const agentId = env.RENTAPERSON_AGENT_ID || '';
  const agentName = env.RENTAPERSON_AGENT_NAME || '';

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The document claims the bridge keeps the API key out of OpenClaw transcripts, but the sample code appends the key directly into the forwarded message body. That means the secret is likely to be stored, logged, or exposed anywhere message content is retained, creating a direct credential disclosure risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The README repeats a false security property: that the API key never appears in transcripts. In reality, the provided bridge code injects the key into the message field, so operators may deploy it believing secrets are protected when they are actually being copied into session content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The recommendation section presents the bridge as 'more secure' because the key supposedly never reaches transcripts, but the implementation does the opposite by forwarding the key inside the message. This mismatch increases the likelihood of unsafe adoption because readers are encouraged toward the insecure option under false assumptions.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · WEBHOOK_API_KEY_SOLUTION.md (reported line 371)May include surrounding context.

md
1. **Test Transform Fix**: Update transform, verify config access, test webhook
2. **Implement Bridge**: Create bridge service, add to setup script, document
3. **Update Setup Script**: Add option to choose bridge vs transform
4. **Update SKILL.md**: Document both approaches

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 · scripts/inject-api-key.js (reported line 22)May include surrounding context.

js
function validate() {
  if (!key || !String(key).trim()) {
    process.stderr.write(
      'inject-api-key: RENTAPERSON_API_KEY is not set. Set it in skills.entries["rent-a-person-ai"].env (e.g. run scripts/setup.js) and restart the gateway.\n'
    );
    process.exit(1);
  }

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 · scripts/rentaperson-inject-key-transform.example.js (reported line 32)May include surrounding context.

js
function validate() {
  if (!key || !String(key).trim()) {
    process.stderr.write(
      'inject-api-key: RENTAPERSON_API_KEY is not set. Set it in skills.entries["rent-a-person-ai"].env (e.g. run scripts/setup.js) and restart the gateway.\n'
    );
    process.exit(1);
  }

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 · scripts/setup.js (reported line 646)May include surrounding context.

js
function validate() {
  if (!key || !String(key).trim()) {
    process.stderr.write(
      'inject-api-key: RENTAPERSON_API_KEY is not set. Set it in skills.entries["rent-a-person-ai"].env (e.g. run scripts/setup.js) and restart the gateway.\n'
    );
    process.exit(1);
  }

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This transform reads a local secret (RENTAPERSON_API_KEY) from config and appends it directly into the message payload as natural-language text. That exposes the credential to downstream agents, logs, webhook receivers, prompt history, and any component that can read the transformed message, which is far broader access than needed for normal request authentication.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/inject-api-key.js:38

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/send-to-session.js:37

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/setup.js:278

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test-setup.js:19

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/fetch-test-ids.js:27

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/setup.js:24

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
bridge/server.js:31

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/fetch-test-ids.js:27

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/inject-api-key.js:22

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/setup.js:546

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
WEBHOOK_API_KEY_SOLUTION.md:189