Back to skill

Security audit

Webhook Relay

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed Webhook Relay guide, but it includes under-warned instructions that can expose private services persistently and send a real webhook signing secret to an external HMAC endpoint.

Review carefully before installing. Use the skill only with non-sensitive demo endpoints unless you understand Webhook Relay's exposure model, avoid sending real webhook signing secrets to /v1/hmac, compute signatures locally instead, do not put real tunnel passwords directly on the command line, and avoid installing the relay as a background service unless you also know how to stop and remove it.

Vulnerability Patterns
  • 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
  • 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)

other

Error
Location
SKILL.md:307
Finding
Webhook Signing Secret Transmitted to an External HMAC Service<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 307–309; the remote API base is defined at line 248 **Vulnerability Type**: Sensitive data exfiltration to a third-party service **Risk Level**: High ### Vulnerable Code ```bash B=https://bin.webhookrelay.com ``` ```bash SIG=$(curl -s -X POST "$B/v1/hmac" -H 'Content-Type: application/json' -d "$(jq -nc \ --arg s "$WEBHOOK_SECRET" --arg b "$(printf %s "$RAW" | base64 | tr -d '\n')" \ '{algorithm:"sha256", secret:$s, body:$b}')" | jq -r .signature) ``` ### Technical Analysis The documented command places the value of `WEBHOOK_SECRET` directly into a JSON request and sends it to `https://bin.webhookrelay.com/v1/hmac`. A webhook signing key is a sensitive authentication credential that allows its holder to generate valid message authentication codes. HMAC calculation can and should be performed locally. Sending the key to a third party unnecessarily expands the trust boundary to include the remote service, its operators, application logs, network infrastructure, backups, and any parties able to compromise those systems. Although TLS protects the request while in transit, it does not prevent the destination service from accessing or retaining the plaintext secret. ### Attack Path 1. A user follows the HMAC verification instructions and stores a real provider signing key in `WEBHOOK_SECRET`. 2. The documented `curl` command serializes that secret into the `secret` property of the request body. 3. The request is transmitted to the externally operated `bin.webhookrelay.com` service. 4. The destination service, its logs, or an attacker who compromises that infrastructure obtains the signing key. 5. The exposed key is used to calculate valid HMAC signatures for attacker-controlled webhook payloads. 6. A receiving application that trusts the signature accepts the forged webhook as authentic. ### Impact Assessment Disclosure of the signing secret can permit forged webhooks for every endp ...[truncated 481 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the recommendation to submit webhook signing secrets to `/v1/hmac`. - Calculate HMAC values locally using a standard cryptographic library or provider-supported SDK. - For example, use `openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"` or a local Python program using the standard `hmac` module. - Avoid placing the secret in command-line arguments because process listings and shell history may expose it. Read it from a protected environment variable, secret manager, or restricted file. - Compare signatures using a constant-time comparison function. - Document provider-specific signing formats, timestamp validation, and replay protection without transmitting key material externally. - Advise users who executed the original command with a real secret to rotate that secret and review webhook activity for forgery attempts. ]]>

T06 · System Persistence

Error
Location
SKILL.md:135
Finding
Relay Agent Installed as a Persistent Operating-System Service<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 135–137 **Vulnerability Type**: Cross-session service persistence **Risk Level**: High ### Vulnerable Code ```bash # …or run the agent as a background OS service: relay service install && relay service start ``` ### Technical Analysis The instructions install and start the relay agent as an operating-system service. Unlike a foreground relay process, an installed service can remain active after the initiating shell or agent session ends and may restart automatically after a system reboot. The relay agent is designed to bridge publicly reachable Webhook Relay infrastructure to localhost, LAN, Kubernetes, or other private destinations. Persisting that bridge changes the host's long-term security posture. If the relay account, local service configuration, or public endpoint is compromised, the persistent service can continue to provide access to internal resources without an active user session. The instructions do not include corresponding stop, disable, or uninstall commands, nor do they require confirmation before establishing persistence. ### Attack Path 1. A user follows the persistent setup instructions and runs `relay service install`. 2. The relay agent is registered with the operating system's service manager. 3. `relay service start` launches the agent outside the lifetime of the current terminal session. 4. Configured public endpoints continue relaying requests to private destinations while the user is absent and potentially after reboot. 5. An attacker obtains access to a public endpoint, relay account, API credential, or improperly protected tunnel. 6. The attacker uses the continuously running relay to reach the configured localhost or private-network service. ### Impact Assessment The service may provide continuing network reachability to internal HTTP or TCP services. The exact privileges available depend on the service account running the agent and the capabilities of ...[truncated 330 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer foreground operation by default so the relay terminates with the user session. - Require explicit, informed user confirmation before installing or enabling an operating-system service. - Clearly explain that the service may survive terminal closure and system reboot. - Add documented commands to stop, disable, and uninstall the service. - Run the service under a dedicated, unprivileged operating-system account. - Restrict the service to only the required buckets, tunnels, destinations, and network interfaces. - Protect relay API credentials through an operating-system secret store and rotate them periodically. - Require authentication and source restrictions for publicly exposed endpoints wherever supported. - Provide a command for enumerating active persistent relays so users can audit unintended exposure. - Record service installation and removal in an auditable system log. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:212
Finding
Tunnel Password Supplied Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 212–214 **Vulnerability Type**: Insecure credential handling in command examples **Risk Level**: Medium ### Vulnerable Code ```bash # Password-protect a demo relay connect -n demo -s demo -c flexible -u alice -p s3cret http://localhost:8080 ``` ### Technical Analysis The example passes a password through the `-p` command-line option. Users are likely to replace the example value with a real password while retaining this invocation pattern. Command-line credentials can be exposed through shell history, process listings, terminal capture, command auditing, CI logs, support transcripts, and agent conversation records. On systems where process arguments are visible to other local users, the credential may be observable while the command is running. The example also embeds a password-like literal without warning that it is only a placeholder and must not be reused. ### Attack Path 1. A user copies the example and replaces `s3cret` with a real tunnel password. 2. The shell records the command in its history, or the operating system exposes it through process metadata while the relay is active. 3. A local user, monitoring tool, log collector, or person with access to the terminal transcript retrieves the password. 4. The attacker connects to the publicly exposed tunnel and authenticates using the recovered credential. 5. The attacker accesses the private service proxied behind the tunnel. ### Impact Assessment Successful exploitation grants the attacker the access protected by the compromised tunnel password. This can expose the proxied development server, internal application, API, or administrative interface. The relay itself does not automatically elevate operating-system privileges, but the attacker obtains the application-level privileges associated with the authenticated tunnel. Further impact depends on vulnerabilities and authorization controls in the destination service. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Do not recommend supplying real passwords directly through command-line arguments. - Prefer an interactive password prompt that disables terminal echo. - If supported, use a protected environment variable, file descriptor, operating-system keychain, or configuration file with restrictive permissions. - Clearly mark example credentials as placeholders and warn users that command-line arguments may be logged or visible in process listings. - Disable or remove affected shell-history entries if a real credential was previously used. - Rotate any password that may have appeared in command history, process telemetry, CI logs, or transcripts. - Use unique, high-entropy tunnel credentials and combine them with source restrictions or application-level authentication where possible. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```

Bin endpoint reference: `POST /v1/bins` (create), `GET /v1/bins/{id}` (read +
requests), `PUT /v1/bins/{id}` (configure response), `DELETE /v1/bins/{id}`,
`(any) /v1/webhooks/{id}` (receiver), `GET /v1/events?stream={id}` (SSE),
`POST /v1/hmac`. Bodies are capped at 500 KB; the service is rate limited (429
when flooded).
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).

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The tunnel section instructs users to expose local or internal services via a public hostname but does not prominently warn that this makes those services internet-reachable. In a security-sensitive skill, omission of an explicit warning can lead users to unintentionally publish development or private services without authentication, IP restrictions, or hardening.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "$B/v1/webhooks/$BIN"

# 3. Send a test request
curl -s -X POST "$B/v1/webhooks/$BIN" -H 'Content-Type: application/json' -d '{"hello":"world"}'

# 4. Read back every captured request as JSON
curl -s "$B/v1/bins/$BIN" | jq '.requests'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
and probabilistic failures (test a sender's retry logic):

```bash
curl -s -X PUT "$B/v1/bins/$BIN" -H 'Content-Type: application/json' -d '{
  "id": "'"$BIN"'",
  "response": {
    "status": 201,
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
RAW=$(curl -s "$B/v1/bins/$BIN" | jq -r '.requests | sort_by(.receivedAt) | last | .body')
# Pipe base64 through `tr -d '\n'` — GNU base64 wraps at 76 cols and would
# embed newlines in the body, producing a wrong signature.
SIG=$(curl -s -X POST "$B/v1/hmac" -H 'Content-Type: application/json' -d "$(jq -nc \
  --arg s "$WEBHOOK_SECRET" --arg b "$(printf %s "$RAW" | base64 | tr -d '\n')" \
  '{algorithm:"sha256", secret:$s, body:$b}')" | jq -r .signature)
echo "expected: sha256=$SIG"
Confidence
82% confidence
Finding
The HMAC verification example sends both the webhook body and the secret to a third-party `/v1/hmac` service for computation. Even though presented as a convenience feature, transmitting shared secrets off-system expands trust boundaries and can expose credentials or sensitive payload data to the external service, logs, or intermediaries.

External Transmission

Medium
Category
Data Exfiltration
Content
- **Forwarding (internal):** start a throwaway server (`python3 -m http.server
  8080`), run `relay forward -b my-app http://localhost:8080`, then
  `curl -X POST https://my.webhookrelay.com/v1/webhooks/<id> -d '{"hi":1}'` and
  watch the agent log + local server receive it.
- **Tunnel:** open the printed `https://<host>` in a browser; requests appear in
  the agent's terminal. Connection errors usually mean the local service is down
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
- **Tunnel:** open the printed `https://<host>` in a browser; requests appear in
  the agent's terminal. Connection errors usually mean the local service is down
  or `--rewrite-host-header` doesn't match what the app expects.
- **Bin:** `BIN=$(curl -s -X POST $B/v1/bins | jq -r .id); curl -s -X POST
  "$B/v1/webhooks/$BIN" -d '{"smoke":1}'; curl -s "$B/v1/bins/$BIN" | jq
  '.requests | length'` should be `>= 1`.
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.