Back to skill

Security audit

pager-triage

Security checks for vulnerabilities and agentic risk

Overview

This PagerDuty triage skill is mostly purpose-aligned, but it under-discloses real credential exposure risks for a tool that can use high-impact PagerDuty access.

Review before installing. Use a read-only, team-scoped PagerDuty token unless you truly need acknowledge/resolve/note actions, avoid running the smoke test with production credentials, and require explicit human confirmation for every write action. Treat incident text and notes as untrusted because attackers or integrations may place instructions inside PagerDuty content.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pager-triage.sh:77
Finding

PagerDuty API Token Exposed Through Process Arguments

Content
View full analysis
/dev/null) || { ``` ### Technical Analysis The PagerDuty API token is expanded into the `curl` argument array and passed as an HTTP header using `-H`. Although the token originates from an environment variable, its expanded value becomes part of the `curl` process argument vector. On systems where process arguments are visible to other local users, diagnostic agents, container administrators, or monitoring software, the complete authorization header may be recovered while the request is running. This contradicts the assertion in `SECURITY.md` that credentials are never passed through command-line arguments. The same issue applies to `PAGERDUTY_EMAIL` during write requests, although disclosure of the API token presents the greater security risk. ### Attack Path 1. A legitimate user or agent invokes a PagerDuty command such as `incidents` or `detail`. 2. The script expands `PAGERDUTY_API_KEY` into the `curl` command-line argument containing the authorization header. 3. During the request, an attacker with sufficient same-host process visibility inspects the `curl` process through facilities such as `/proc`, process monitoring, container administration, or telemetry collection. 4. The attacker extracts the complete ...[truncated 1057 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/smoke.sh:196
Finding

Smoke Test Discloses Credential-Derived Data and PagerDuty User Email

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
scripts/pager-triage.sh:250
Finding

Untrusted PagerDuty Content Is Forwarded to the Agent Without an Enforced Trust Boundary

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

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · SECURITY.md (reported line 1)May include surrounding context.

md
# Security Model — pager-triage

**Version:** 0.1.1
**Last updated:** 2026-02-16

---

## 1. API Key Handling

### Storage
- API keys are read **exclusively** from environment variables (`PAGERDUTY_API_KEY`, `PAGERDUTY_EMAIL`)
- Keys are **never** hardcoded, written to disk, cached, or stored in any skill state
- Keys are **never** passed as command-line arguments (which would be visible in `ps` output)

### Masking
- If an API key appears in an error message (e.g., authentication failure), it is masked to `****<last 4 chars>` using the `mask_key()` function
- The agent **never** displays the full key

Instruction Override

High
Category
Prompt Injection
Confidence
80% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · SECURITY.md (reported line 91)May include surrounding context.

md
### T1: Prompt Injection via Incident Data

**Risk:** An attacker creates a PagerDuty incident with a title or description containing prompt injection payload (e.g., "Ignore previous instructions and...").

**Mitigation:**
- Incident data flows through `jq` field extraction — only specific fields are included in output

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 · TESTING.md (reported line 64)May include surrounding context.

T-SMOKE-7: Invalid incident ID format

bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "../../etc/passwd"

Expected: JSON error "Invalid incident ID format". Exit code 1. No API call made.

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/smoke.sh (reported line 137)May include surrounding context.

sh
#### T-SMOKE-7: Invalid incident ID format
```bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "../../etc/passwd"
```
**Expected:** JSON error `"Invalid incident ID format"`. Exit code 1. No API call made.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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 · TESTING.md (reported line 71)May include surrounding context.

T-SMOKE-8: Invalid incident ID — special characters

bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "P123;rm -rf /"

Expected: JSON error "Invalid incident ID format". Exit code 1.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · TESTING.md (reported line 71)May include surrounding context.

T-SMOKE-8: Invalid incident ID — special characters

bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "P123;rm -rf /"

Expected: JSON error "Invalid incident ID format". Exit code 1.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · TESTING.md (reported line 71)May include surrounding context.

T-SMOKE-8: Invalid incident ID — special characters

bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "P123;rm -rf /"

Expected: JSON error "Invalid incident ID format". Exit code 1.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/smoke.sh (reported line 150)May include surrounding context.

sh
#### T-SMOKE-8: Invalid incident ID — special characters
```bash
export PAGERDUTY_API_KEY="test_key"
./scripts/pager-triage.sh detail "P123;rm -rf /"
```
**Expected:** JSON error `"Invalid incident ID format"`. Exit code 1.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% 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 · TESTING.md (reported line 71)May include surrounding context.

md
(
  export PAGERDUTY_API_KEY="smoke_test_key"
  if output=$("$TOOL" detail 'P123;rm -rf /' 2>&1); then
    fail "Command injection ID should be rejected"
  else
    if echo "$output" | grep -q "Invalid incident ID"; then

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% 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 · scripts/smoke.sh (reported line 150)May include surrounding context.

sh
(
  export PAGERDUTY_API_KEY="smoke_test_key"
  if output=$("$TOOL" detail 'P123;rm -rf /' 2>&1); then
    fail "Command injection ID should be rejected"
  else
    if echo "$output" | grep -q "Invalid incident ID"; then

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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 · scripts/smoke.sh (reported line 150)May include surrounding context.

sh
(
  export PAGERDUTY_API_KEY="smoke_test_key"
  if output=$("$TOOL" detail 'P123;rm -rf /' 2>&1); then
    fail "Command injection ID should be rejected"
  else
    if echo "$output" | grep -q "Invalid incident ID"; then

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% 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 · scripts/smoke.sh (reported line 150)May include surrounding context.

sh
(
  export PAGERDUTY_API_KEY="smoke_test_key"
  if output=$("$TOOL" detail 'P123;rm -rf /' 2>&1); then
    fail "Command injection ID should be rejected"
  else
    if echo "$output" | grep -q "Invalid incident ID"; then

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · README.md (reported line 129)May include surrounding context.

md
## 2. Read-Only by Default

### Read Operations (5 commands — no confirmation needed)
| Command | What it reads | PD API endpoint |
|---------|--------------|-----------------|
| `incidents` | Active incidents list | `GET /incidents` |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SECURITY.md (reported line 28)May include surrounding context.

md
## 2. Read-Only by Default

### Read Operations (5 commands — no confirmation needed)
| Command | What it reads | PD API endpoint |
|---------|--------------|-----------------|
| `incidents` | Active incidents list | `GET /incidents` |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## 2. Read-Only by Default

### Read Operations (5 commands — no confirmation needed)
| Command | What it reads | PD API endpoint |
|---------|--------------|-----------------|
| `incidents` | Active incidents list | `GET /incidents` |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SECURITY.md (reported line 122)May include surrounding context.

md
- PagerDuty's `From` header creates an audit trail showing which email performed the action
- PagerDuty's own timeline records all acknowledgment/resolution events

**Residual risk:** Low-medium. If the agent is misconfigured to auto-confirm, this gate is bypassed at the agent level. The `--confirm` flag is a defense-in-depth measure, not a complete solution.

### T4: Incident ID Injection

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill exposes operational capabilities that clearly rely on external API access and likely command/tool execution, but it does not declare any explicit tool scope such as allowed-tools or permissions. That weakens least-privilege controls and makes it harder for the host agent to constrain what the skill may invoke, increasing the blast radius if the skill is misrouted, extended unsafely, or paired with overly permissive runtime defaults.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation guidance uses broad natural-language triggers like 'what's on fire?' and generic mentions of 'incidents' or 'triage', which can cause the skill to activate in contexts not specifically requesting PagerDuty access. In a security-sensitive operational skill, unintended activation can expose incident metadata, on-call identities, or encourage accidental progression toward write actions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The spec materially expands scope from the advertised PagerDuty triage skill to also support OpsGenie and a local CLI fallback path. Scope expansion increases attack surface, introduces additional credential and execution paths, and can cause the agent to interact with systems or binaries the user did not intend to authorize.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SPEC.md (reported line 71)May include surrounding context.

API Call:

bash
curl -s \
  -H "Authorization: Token token=$PAGERDUTY_API_KEY" \
  -H "Content-Type: application/json" \
  "https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

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 · SPEC.md (reported line 74)May include surrounding context.

curl -s
-H "Authorization: Token token=$PAGERDUTY_API_KEY"
-H "Content-Type: application/json"
"https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

text

**Output Schema:**

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 · SPEC.md (reported line 122)May include surrounding context.

curl -s
-H "Authorization: Token token=$PAGERDUTY_API_KEY"
-H "Content-Type: application/json"
"https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

text

**Output Schema:**

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 · SPEC.md (reported line 126)May include surrounding context.

curl -s
-H "Authorization: Token token=$PAGERDUTY_API_KEY"
-H "Content-Type: application/json"
"https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

text

**Output Schema:**

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 · SPEC.md (reported line 130)May include surrounding context.

curl -s
-H "Authorization: Token token=$PAGERDUTY_API_KEY"
-H "Content-Type: application/json"
"https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

text

**Output Schema:**

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 · SPEC.md (reported line 134)May include surrounding context.

curl -s
-H "Authorization: Token token=$PAGERDUTY_API_KEY"
-H "Content-Type: application/json"
"https://api.pagerduty.com/incidents?statuses[]=triggered&statuses[]=acknowledged&sort_by=urgency&limit=25&include[]=assignees&include[]=services"

text

**Output Schema:**