Back to skill

Security audit

JWT Debugger

Security checks for vulnerabilities and agentic risk

Overview

This is a local JWT debugging skill, but some validation commands can execute injected Python if a token or key value is maliciously crafted.

Review before installing. The skill avoids external JWT websites and has no persistence, but its validation examples should be rewritten to pass tokens, secrets, keys, and audiences through stdin, files, or environment variables read by Python, not embedded into python3 -c source. Do not run the current validation snippets on tokens or key material supplied by an untrusted party.

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:84
Finding
Arbitrary Python Code Execution Through Unsafe JWT Parameter Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 84–85 and 98–100 **Vulnerability Type**: User-controlled input embedded directly into Python source code **Risk Level**: High ### Vulnerable Code ```python token = '$TOKEN' secret = '$SECRET' ``` ```python import jwt # pip install PyJWT[crypto] try: decoded = jwt.decode('$TOKEN', '$PUBLIC_KEY', algorithms=['RS256'], audience='$EXPECTED_AUD') ``` These statements occur inside double-quoted `python3 -c` shell commands. The shell expands `$TOKEN`, `$SECRET`, `$PUBLIC_KEY`, and `$EXPECTED_AUD` before the resulting text is parsed as Python source. ### Technical Analysis The commands directly interpolate JWT-related values into single-quoted Python string literals. No escaping or safe argument-passing mechanism is used. If an attacker controls any interpolated value, a single quote can terminate the intended Python literal. The remaining value can then introduce arbitrary Python statements. For example, a malicious token value shaped like the following could escape the assignment and execute another statement: ```text '; __import__("os").system("attacker-controlled-command"); # ``` After shell expansion, the generated Python source would be equivalent to: ```python token = ''; __import__("os").system("attacker-controlled-command"); #' ``` Multiline public-key data also commonly contains line breaks. Embedding such data directly into a single-quoted Python literal can break parsing even when it is not malicious, while a deliberately crafted key can use the same condition for code injection. This is not merely a JWT validation failure. The input is inserted into the source code of the Python interpreter itself, creating an arbitrary local code-execution primitive. ### Attack Path 1. An attacker supplies or influences a token, secret, public key, or expected-audience value processed using the documented validation commands. 2. The supplied value includes a quote that closes the in ...[truncated 1337 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not place tokens, secrets, keys, audiences, or any other externally influenced values inside dynamically generated Python source. 1. Pass values through environment variables and retrieve them with `os.environ`: ```bash TOKEN="$TOKEN" SECRET="$SECRET" python3 -c ' import os import hmac import hashlib import base64 token = os.environ["TOKEN"] secret = os.environ["SECRET"] parts = token.split(".") if len(parts) != 3: raise SystemExit("Invalid JWT: expected three parts") signing_input = f"{parts[0]}.{parts[1]}".encode() signature = base64.urlsafe_b64decode(parts[2] + "==") expected = hmac.new(secret.encode(), signing_input, hashlib.sha256).digest() print("Signature VALID" if hmac.compare_digest(signature, expected) else "Signature INVALID") ' ``` 2. For public keys, use a key file or standard input rather than embedding multiline PEM data into source code: ```bash python3 verify_jwt.py --token "$TOKEN" --public-key-file "$PUBLIC_KEY_FILE" \ --audience "$EXPECTED_AUD" ``` 3. Prefer a dedicated, version-controlled Python script using `argparse` or another structured interface instead of complex inline `python3 -c` programs. 4. Validate the JWT structure before indexing token components, and reject malformed input with a controlled error. 5. Avoid exposing secrets in command-line arguments where they may be visible in process listings or shell history. Standard input, protected files, or a secret-management mechanism should be used for sensitive keys. 6. Add regression tests containing quotes, backslashes, newlines, malformed JWTs, and multiline PEM keys to confirm that all inputs are treated exclusively as data and can never alter executable code. ]]>
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Vague Triggers

Medium
Confidence
92% confidence
Finding
The invocation guidance includes broad phrases like "decode this token", "why is auth failing", and especially the fallback condition "when troubleshooting authentication," which can overlap with many general authentication support requests. The description does not provide exclusion conditions or boundaries for when this JWT-specific skill should not activate, increasing the chance of unintended invocation.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest and introductory documentation describe a troubleshooting tool for inspecting and validating existing tokens in authentication flows. The `generate` command expands the skill into token creation, which is a distinct capability not reflected in the stated description of decoding, validation, debugging, or diagnosis.

Static analysis

No suspicious patterns detected.