Back to skill

Security audit

Saved Markdown

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its public publishing purpose, but it under-discloses privacy-sensitive publication flows and tells agents to store page deletion phrases in a local plaintext log.

Install only if you intend to publish content to a public saved.md URL. Review and redact sensitive, personal, confidential, or third-party material before publishing, and disable or change the entries.json logging behavior so deletion phrases are not stored in plaintext or committed/shared.

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

Warning
Location
CLAUDE.md:12
Finding

Plaintext Persistence of Page Deletion Credentials

Content
View full analysis

Vulnerability Details

File Location: CLAUDE.md, line 12
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: Medium

Vulnerable Code

markdown
- **`entries.json`** — Append-only log of all published pages. Every publish must log here with id, url, deletePhrase, title, contentType, sizeBytes, and createdAt.

Technical Analysis

The repository instructs the agent to save every published page's deletePhrase in entries.json. A deletion phrase is a page-control credential because possession may grant authority to delete its associated published page.

Persisting this credential in a plaintext, append-only project file violates secure secret-storage and least-exposure principles. The credential could subsequently be exposed through source-control commits, repository sharing, backups, build artifacts, diagnostic collection, or access by another local process or user.

This persistence requirement is documented in CLAUDE.md but is not disclosed in the publishing workflow in SKILL.md, making it an unexpected security-sensitive side effect. At audit time, entries.json contained an empty entries array, so no deletion credential was currently exposed.

Attack Path

  1. A user asks the Skill to publish content to saved.md.
  2. The publication service returns page metadata that includes a deletion phrase.
  3. Following CLAUDE.md, the agent appends the page URL, title, deletion phrase, and related metadata to entries.json.
  4. The populated file is committed, shared, backed up, included in an artifact, or read by another party with project access.
  5. The party extracts the plaintext deletion phrase.
  6. Where the service accepts that phrase as deletion authorization, the party uses it to delete the associated public page.

Impact Assessment

Successful exploitation could grant unauthorized deletion authority over each page whose deletion phrase is recorded. It may also reveal publication history, document ...[truncated 250 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove deletePhrase from the entries.json logging schema.
  2. Do not write deletion credentials to tracked repository files, ordinary logs, console output, or generated artifacts.
  3. Return the deletion phrase directly to the requesting user through the intended secure response channel.
  4. If persistence is explicitly required, use an operating-system credential manager or encrypted secret store with narrowly scoped access controls.
  5. Apply restrictive filesystem permissions to any local metadata that must be retained.
  6. Add local publication metadata files to .gitignore and artifact-exclusion rules.
  7. Document all retained publication metadata and obtain user consent before storing security-sensitive values.
  8. Rotate or invalidate any deletion phrases previously written to shared or committed copies of the log.
  9. Add validation or automated secret scanning that rejects commits containing fields such as deletePhrase.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (22)

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 · templates/markdowns/documentation-guide.md (reported line 181)May include surrounding context.

git clone https://github.com/example/app.git cd app pnpm install cp .env.example .env pnpm dev

text

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 · templates/markdowns/documentation-guide.md (reported line 210)May include surrounding context.

git clone https://github.com/example/app.git cd app pnpm install cp .env.example .env pnpm dev

text

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 · templates/markdowns/documentation-guide.md (reported line 278)May include surrounding context.

md
| `ECONNREFUSED 127.0.0.1:5432` | PostgreSQL not running | Start with `brew services start postgresql@15` |
| `pnpm: command not found` | pnpm not installed | Install: `npm install -g pnpm` |
| Migrations fail with "relation already exists" | DB not clean | Drop and recreate: `dropdb app_dev && createdb app_dev` |
| Port 3000 already in use | Another process on that port | Kill it: `lsof -ti:3000 \| xargs kill` or change PORT in .env |

---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly publishes user-provided content to an external public service and emphasizes anonymous sharing, but this guidance does not include any warning, consent checkpoint, or data-handling notice. In an agent context, that omission is risky because users may provide sensitive drafts, internal notes, or proprietary content without realizing it will be transmitted off-system and exposed via a public URL.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly publishes content to a public shareable URL but does not require a clear user-facing warning or confirmation that the content will be publicly accessible and anonymously hosted. This creates a realistic risk that users may unintentionally expose sensitive, proprietary, or personal information, especially because the workflow encourages immediate publish flows such as one-shot mode.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The remix workflow instructs the agent to fetch existing saved.md content and republish edited material under a new public URL without any privacy or ownership warning. This can lead to accidental redistribution of sensitive or third-party content, and users may not realize that remixing preserves public exposure while creating an additional immutable copy.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction says to use this workflow when the user wants a new scaffold from a screenshot, description, or rough idea, but it does not define clear boundaries for what counts as a template request versus a general content-generation request. This ambiguity could cause unintended invocation for everyday requests that mention a vague idea or screenshot.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file includes natural-language HTML examples that hard-code the document language to English with <html lang="en">. The template does not offer a language/locale choice or explain why English is required, which can violate language/locale policy for users expecting localized output.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The 'When to Use This Template' section activates on generic requests like 'documentation,' 'guide,' 'instructions,' and 'steps' without narrowing context or providing exclusion conditions. These terms are common in everyday technical conversations, so the template could be selected in situations where a more specific skill would be more appropriate.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The template's trigger conditions are broad enough to match generic report, analysis, summary, audit, and assessment requests, which can cause the publishing skill to activate for ordinary content-generation tasks that do not clearly imply saved.md publication. In this skill's context, that increases the chance of routing sensitive business, security, or audit content into a public-hosting workflow and creating unintended data exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The template explicitly encourages publishing email, phone, and location details in a publicly shareable page without any privacy warning or minimization guidance. In the context of a public hosting skill, this increases the risk of oversharing personally identifiable information, spam, doxxing, or unwanted contact, especially if users paste sensitive details by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The HTML template sets <html lang="en">, which establishes English as the default language for generated output. Because this skill is a general company-profile template rather than a clearly region-specific tool, forcing a specific language can violate the language/locale policy when no user choice or opt-in is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example HTML repeats <html lang="en">, reinforcing English-only output in the natural-language guidance of the file. Since the template is intended for broad reuse and does not mention user locale selection, this is a policy-relevant language constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The template sets lang="en" in the HTML root, and the example repeats this later. Because this is a general-purpose dashboard template rather than a clearly region-specific tool, hard-coding English can violate language/locale policy by implicitly forcing one locale without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The sample dashboard uses lang="en" again in the example block. Repeating the fixed English locale reinforces a default-language behavior without presenting localization as configurable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML template sets lang="en", which forces an English locale in the generated output. The file does not indicate that English is optional or that this template is intended only for English-language events, so it can conflict with language-choice policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The example HTML uses lang="en", reinforcing an English-only default in a file that otherwise does not ask the user for preferred language. This is a natural-language policy concern because it normalizes a fixed locale rather than offering user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The scaffold sets <html lang="en">, which forces generated pages to declare English regardless of the user's desired language or locale. This is a natural-language/locale policy concern because the template does not offer opt-in, substitution guidance, or any justification for restricting output to English.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The worked example repeats the same locale constraint by setting <html lang="en"> in the sample output. Because examples often get copied directly, this reinforces an English-only default without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The template sets <html lang="en">, which forces an English locale in the generated document. Because this is a general-purpose resume/CV template rather than a clearly region-specific skill, it should not impose English by default without user opt-in or guidance to adapt the locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The example HTML repeats <html lang="en">, again prescribing English for a broadly applicable template. This can conflict with language/locale policy unless the user has chosen English or the template explains why that locale is required.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The template activates on a wide set of phrases such as 'personal profile,' 'personal page,' 'career page,' and 'bio page' without clear exclusion conditions. These terms can apply to many non-resume contexts, which may cause unintended use of this template when a user wants a different kind of profile or webpage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.