Back to skill

Security audit

Heroku Platform API

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Heroku API helper, but it needs review because some examples bypass its promised write-confirmation guard and fetch logs or Heroku-returned URLs outside the stated network boundary.

Install only if you are comfortable giving an agent access to Heroku operations for the apps covered by your token. Use the narrowest scoped token possible, keep HEROKU_PERMISSION=readonly by default, avoid global Heroku tokens, do not enable the noninteractive write override unless you have external controls, and manually review any deploy, CI/CD, log, backup, webhook, or production-changing command before running it.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:598
Finding

Write Operations Bypass the Declared Permission and Confirmation Guard

Content
View full analysis
/dev/null echo " Maintenance: ON" fi # Step 3: Create backup (production only) if [[ "$ENV" == "production" ]]; then echo "── Step 3: Creating database backup ──" PG_ID=$(heroku_api GET "/apps/$APP/addons" | \ jq -r '.[] | select(.addon_service.name=="heroku-postgresql") | .id') curl -sf - ...[truncated 4490 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (35)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill promises destructive actions always require interactive confirmation, but explicitly allows non-interactive writes when HEROKU_NONINTERACTIVE_WRITES=i-accept-the-risk is set. In autonomous or CI contexts, this converts a human-approval gate into a single environment toggle, enabling destructive operations without per-action consent.

Content

No source excerpt is available for this finding.

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

Delete app (DESTRUCTIVE — always confirm with user)

bash
heroku_api DELETE "/apps/my-app-staging"

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

Restart all dynos

bash
heroku_api DELETE "/apps/my-app-staging/dynos"

Restart a specific dyno

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

Restart a specific dyno

bash
heroku_api DELETE "/apps/my-app-staging/dynos/web.1"

Run one-off dyno (e.g., migration)

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill asserts it only contacts api.heroku.com and postgres-api.heroku.com, but several examples dereference Heroku-returned URLs such as build output streams, source upload URLs, backup public URLs, and Logplex URLs on other hosts. This weakens network-boundary guarantees and can cause sensitive data or credentials-adjacent context to be transmitted to unlisted domains, especially in agented environments that rely on metadata allowlists.

Content

No source excerpt is available for this finding.

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

Delete add-on (DESTRUCTIVE)

bash
heroku_api DELETE "/apps/my-app-staging/addons/$ADDON_ID"

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

Delete domain

bash
heroku_api DELETE "/apps/my-app-staging/domains/staging.myapp.dev"

SSL/SNI Endpoints

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The log-reading flow chains a POST to Heroku into xargs curl against a returned logplex_url, causing the agent to make a second request to an arbitrary URL supplied by the first response. This is a classic chaining risk because it expands outbound access beyond the declared hosts and can stream sensitive logs into the local context without validating the destination.

Content

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

"dyno": "web", "lines": 100, "tail": false }' | jq -r '.logplex_url' | xargs curl -sf

text

### Read worker dyno logs

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This worker-log example has the same unsafe chaining pattern: a response-derived URL is blindly fetched with curl. Because worker logs often contain job payloads and secrets, the combination of arbitrary follow-on fetch and sensitive content materially raises exfiltration risk.

Content

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

"dyno": "worker", "lines": 100, "tail": false }' | jq -r '.logplex_url' | xargs curl -sf

text

### Tail logs real-time (web)

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Fetching all dyno logs via a response-derived URL magnifies both chaining and data-exposure risk, since it can include app, worker, router, and platform logs in one stream. In agent contexts this is especially dangerous because broad operational context may be copied, summarized, or relayed onward.

Content

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

heroku_api POST "/apps/my-app-staging/log-sessions" '{ "lines": 200, "tail": false }' | jq -r '.logplex_url' | xargs curl -sf

text

### Read logs from specific dyno (by name)

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This specific-dyno example still blindly dereferences a returned URL using xargs curl. Even when scoped to one dyno, it normalizes unsafe response-to-tool chaining without destination checks.

Content

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

md
"dyno": "web.1",
  "lines": 100,
  "tail": false
}' | jq -r '.logplex_url' | xargs curl -sf

# Example: only worker.2
heroku_api POST "/apps/my-app-staging/log-sessions" '{

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The second specific-dyno example repeats the same unsafe chaining pattern. Repetition across the skill increases the likelihood that users copy insecure idioms into automation.

Content

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

"dyno": "worker.2", "lines": 100, "tail": false }' | jq -r '.logplex_url' | xargs curl -sf

text

### Router logs only (request timing, status codes)

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Router-log retrieval blindly follows a returned URL and then exposes potentially sensitive request metadata such as paths, hosts, statuses, and timing. This combines unsafe chaining with privacy and reconnaissance concerns.

Content

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

"dyno": "router", "lines": 200, "tail": false }' | jq -r '.logplex_url' | xargs curl -sf

text

### Log filter with grep (pattern matching)

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The reusable app_logs_grep helper institutionalizes unsafe response-driven chaining by piping a returned URL into xargs curl and then grep. Because it is presented as a helper for many later examples, it spreads the vulnerable pattern throughout the skill and makes bulk sensitive-log extraction trivial.

Content

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

local pattern="$3"

heroku_api POST "/apps/$app/log-sessions" "$payload" |
jq -r '.logplex_url' | xargs curl -sf | grep -iE "$pattern" }

text

Context Leakage

High
Category
Data Exfiltration
Confidence
88% confidence
Finding

The log-session workflows fetch application and platform logs, which can contain secrets, credentials, cookies, PII, internal URLs, stack traces, and operational metadata, then stream them into the agent context and shell pipelines. In agent settings this is a context-leakage risk because highly sensitive runtime data becomes available for further processing, display, storage, or onward transmission.

Content

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

md
---

### Log session parameters reference

| Parameter | Type    | Description                                           |
|-----------|---------|-------------------------------------------------------|

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

}'

Delete log drain (⚠️ full only — ask first)

heroku_api DELETE "/apps/my-app-staging/log-drains/DRAIN_ID"

text

---

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

Delete review app

bash
heroku_api DELETE "/review-apps/REVIEW_APP_ID"

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

Remove collaborator

bash
heroku_api DELETE "/apps/my-app-staging/collaborators/dev@myapp.dev"

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The 'Safe Deploy Script' directly performs maintenance toggles, backups, one-off dyno creation, and dyno restarts using an unguarded helper that omits the documented permission and confirmation controls. Because it is presented as safe, users are more likely to trust and reuse it, which can lead to unauthorized production changes or outages in non-interactive environments.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

Within the deploy script, restart-all-dynos is executed through a local heroku_api function that omits the documented permission and confirmation guard, making this destructive parameter actionable without the promised protections. In production, this can cause immediate service disruption or compound a failed deployment.

Content

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

md
# Step 5: Restart dynos
echo "── Step 5: Restarting dynos ──"
heroku_api DELETE "/apps/$APP/dynos" > /dev/null
echo "  All dynos restarted"

# Step 6: Disable maintenance

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This is a manifest file, so vague-trigger review applies. The description presents the skill as a 'Full-featured' manager covering a very wide range of Heroku operations, but it does not specify concrete trigger phrases, activation boundaries, or exclusion conditions, which can make invocation matching overly broad in registries that rely on description text.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The security manifest claims only HEROKU_API_KEY and HEROKU_PERMISSION are accessed, but heroku_guard also reads HEROKU_NONINTERACTIVE_WRITES. In security-sensitive registries, incomplete disclosure of environment-variable usage undermines review and can hide a control that materially changes write behavior.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

bash
# Verify token is valid
curl -sf https://api.heroku.com/account \
  -H "Authorization: Bearer $HEROKU_API_KEY" \
  -H "Accept: application/vnd.heroku+json; version=3" | jq '.email'

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

bash
# Verify token is valid
curl -sf https://api.heroku.com/account \
  -H "Authorization: Bearer $HEROKU_API_KEY" \
  -H "Accept: application/vnd.heroku+json; version=3" | jq '.email'

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

bash
# Verify token is valid
curl -sf https://api.heroku.com/account \
  -H "Authorization: Bearer $HEROKU_API_KEY" \
  -H "Accept: application/vnd.heroku+json; version=3" | jq '.email'

Static analysis

No suspicious patterns detected.