T09 · Insecure Skill Coding Practices
- Location
SKILL.md:484- Finding
Plaintext Secret Values May Be Exposed in Environment Scan Reports
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This local JWT audit skill is mostly purpose-aligned, but it can scan credential-bearing .env files and may print weak secret values into reports.
Review before installing. Use this only on repositories and env files you intend to audit, avoid broad workspace scans, and treat any generated report as sensitive because it may include secret values. Rotate any real secret that appears in output.
SKILL.md:484Plaintext Secret Values May Be Exposed in Environment Scan Reports
The metadata advertises scanning .env files and hardcoded tokens, which implies the skill is designed to access credential-bearing material. In context this is part of a legitimate security audit, but credential access remains sensitive because it can expose secrets if scope, redaction, or output handling are weak.
---
name: JWT Auth Audit
description: JWT and OAuth/OIDC security auditor. Decodes any JWT token (without verification) to inspect alg/exp/iss/aud/scope claims, detects the "alg:none" bypass vulnerability, expired or no-expiry tokens, overly broad OAuth scopes, JWT stored in localStorage (XSS theft risk), JWT in URL parameters (log leakage), missing issuer/audience validation in source code, hardcoded tokens in .env files, and weak HMAC secrets. Also scans source files for insecure token handling patterns: Bearer token logged, token compared with ==, auth bypass via role:admin in payload. Generates a severity-ranked report with exact code locations and fixes. Zero external API — pure local analysis. Triggers on "JWT audit", "token security", "auth security", "alg none", "OAuth scopes", "bearer token", "token expiry", "/jwt-audit".
license: Apache-2.0
homepage: https://canlah.ai
metadata:
The documented command /jwt-audit --env-scan explicitly instructs scanning .env files, which commonly contain live secrets. This is contextually legitimate for a security tool, but still increases the risk of exposing credentials through logs, reports, or overbroad workspace access.
# Option 2: Audit source code for insecure token handling
/jwt-audit --scan src/
# Option 3: Audit .env files for hardcoded tokens
/jwt-audit --env-scan
# Option 4: Audit a specific auth file
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
issue=f'Token expires in {ttl//86400} days — very long-lived',
detail='Long-lived tokens increase the window of exposure after theft.',
fix=(
'Use short-lived access tokens (≤1 hour) + refresh tokens. '
'For JWTs: exp should be 15min–1hr for sensitive endpoints.'
),
))
The section dedicated to scanning .env files indicates intentional access to high-value secret storage. While consistent with the skill's purpose, the danger comes from normalizing broad secret-file inspection without built-in safeguards around redaction and scope.
import os
scan_env_files(root='.') defaults to scanning the current directory tree for sensitive configuration files, which can access credentials beyond the user’s immediate intent. Because .env files often hold production secrets, broad default credential discovery materially raises exposure risk even in a legitimate auditing tool.
def scan_env_files(root: str = '.') -> list[dict]:
"""Scan .env files for hardcoded tokens and weak secrets."""
findings = []
env_files = []
Enumerating .env.production specifically reaches into high-risk production secret storage. If run on a mixed workspace, this can expose live credentials with greater impact than development tokens.
findings = []
env_files = []
for pattern in ['.env', '.env.local', '.env.production', '.env.*']:
env_files.extend(glob.glob(f'{root}/{pattern}'))
for env_path in env_files:
Enumerating .env.production specifically reaches into high-risk production secret storage. If run on a mixed workspace, this can expose live credentials with greater impact than development tokens.
findings = []
env_files = []
for pattern in ['.env', '.env.local', '.env.production', '.env.*']:
env_files.extend(glob.glob(f'{root}/{pattern}'))
for env_path in env_files:
Enumerating .env.production specifically reaches into high-risk production secret storage. If run on a mixed workspace, this can expose live credentials with greater impact than development tokens.
findings = []
env_files = []
for pattern in ['.env', '.env.local', '.env.production', '.env.*']:
env_files.extend(glob.glob(f'{root}/{pattern}'))
for env_path in env_files:
The code checks env values against a JWT-like regex, meaning it reads and inspects raw secret-bearing values from .env files. This is inherently sensitive because it processes actual credential material and could leak it if outputs or logs are mishandled.
key = key.strip()
value = value.strip().strip('"\'')
# JWT token value in .env
if JWT_PATTERN.match(value):
findings.append({
'file': env_path,
The finding text references a "JWT token hardcoded in .env file," confirming the skill is intended to inspect and classify credential contents. That is useful for security review, but it also means the skill handles live secret data and therefore needs strict output hygiene.
'file': env_path,
'line': i,
'key': key,
'issue': 'JWT token hardcoded in .env file',
'severity': 'HIGH',
'fix': 'Generate dynamic tokens at runtime. Store only the signing secret, not a token.',
})
The sample report includes an ".env scan" summary, which suggests discovered secret-related findings may be surfaced in generated output. Reporting is expected, but if not carefully redacted it can become a secondary credential disclosure channel.
## JWT & Auth Security Audit
Token analyzed: eyJhbGci... | Source scan: src/ | .env scan: .
---
The example output prints .env:3 — JWT_SECRET=mysecret, directly echoing the secret value in the report. This is a concrete credential disclosure issue: even weak or sample secrets should not be reproduced in generated audit artifacts because reports are often shared, logged, or stored.
---
### .env Findings
`.env:3` — `JWT_SECRET=mysecret` — **CRITICAL: Weak secret**
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.
---
name: JWT Auth Audit
description: JWT and OAuth/OIDC security auditor. Decodes any JWT token (without verification) to inspect alg/exp/iss/aud/scope claims, detects the "alg:none" bypass vulnerability, expired or no-expiry tokens, overly broad OAuth scopes, JWT stored in localStorage (XSS theft risk), JWT in URL parameters (log leakage), missing issuer/audience validation in source code, hardcoded tokens in .env files, and weak HMAC secrets. Also scans source files for insecure token handling patterns: Bearer token logged, token compared with ==, auth bypass via role:admin in payload. Generates a severity-ranked report with exact code locations and fixes. Zero external API — pure local analysis. Triggers on "JWT audit", "token security", "auth security", "alg none", "OAuth scopes", "bearer token", "token expiry", "/jwt-audit".
license: Apache-2.0
homepage: https://canlah.ai
metadata:
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.
---
name: JWT Auth Audit
description: JWT and OAuth/OIDC security auditor. Decodes any JWT token (without verification) to inspect alg/exp/iss/aud/scope claims, detects the "alg:none" bypass vulnerability, expired or no-expiry tokens, overly broad OAuth scopes, JWT stored in localStorage (XSS theft risk), JWT in URL parameters (log leakage), missing issuer/audience validation in source code, hardcoded tokens in .env files, and weak HMAC secrets. Also scans source files for insecure token handling patterns: Bearer token logged, token compared with ==, auth bypass via role:admin in payload. Generates a severity-ranked report with exact code locations and fixes. Zero external API — pure local analysis. Triggers on "JWT audit", "token security", "auth security", "alg none", "OAuth scopes", "bearer token", "token expiry", "/jwt-audit".
license: Apache-2.0
homepage: https://canlah.ai
metadata:
The metadata trigger list includes broad phrases like "token security" and "auth security" that could cause the skill to activate on general conversation rather than an explicit audit request. This is not a code-execution flaw, but it increases the chance of unintended invocation on sensitive content such as pasted tokens or source snippets.
The Trigger Phrases section repeats ambiguous activators like "auth security" and "token expiry" without requiring a clear opt-in. In a skill that handles credentials and scans code, accidental invocation can expose or over-process sensitive authentication material.
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
import os
The function scans for .env files from the provided root and can enumerate sensitive configuration files across a workspace. In a security-audit skill this behavior is aligned with stated purpose, but it still creates real exposure because .env files commonly contain credentials, tokens, and private keys.
def scan_env_files(root: str = '.') -> list[dict]:
"""Scan .env files for hardcoded tokens and weak secrets."""
findings = []
env_files = []