Back to skill

Security audit

Senior Frontend

Security checks for vulnerabilities and agentic risk

Overview

This is a frontend scaffolding and guidance skill with some examples users should review carefully, but I found no hidden exfiltration, persistence, or deceptive behavior.

Use this skill in a normal project workspace, review generated files before keeping them, and use dry-run when possible. Before running npm install, pin or review dependency versions instead of accepting generated "latest" entries. Do not copy the documented auth-token localStorage pattern into production; prefer server-managed HttpOnly secure cookies or keep sensitive tokens out of persistent browser storage.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/frontend_scaffolder.py:642
Finding

Generated Feature Dependencies Use the Mutable latest Version

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/react_patterns.md:403
Finding

Authentication Token Is Persisted in Browser-Accessible Storage

Content
View full analysis
Promise; logout: () => void; } const useAuthStore = create()( persist( (set) => ({ user: null, token: null, login: async (email, password) => { const { user, token } = await authAPI.login(email, password); set({ user, token }); }, logout: () => set({ user: null, token: null }), }), { name: 'auth-storage' } ) ); ``` ### Technical Analysis Zustand’s `persist` middleware serializes the store under the `auth-storage` key. Because no `partialize` or alternative secure storage mechanism is configured, the persisted state includes the returned authentication token. Browser storage is accessible to JavaScript executing under the application’s origin. Unlike an `HttpOnly` cookie, a token in local storage cannot be protected from a successful cross-site scripting attack. Compromised same-origin third-party scripts or malicious browser extensions with appropriate access may also obtain it. The call to `authAPI.login(email, password)` is an abstract authentication operation and does not identify an attacker-controlled endpoint. Sending credentials to a legitimate authentication service is necessary for the feature. The confirmed weakness is persistence of the returned token, not the existence of the login request. ### Attack Path 1. An application adopts the documented Zustand authentication pattern. 2. A user logs in successfully. 3. `authAPI.login` returns an authentication token. 4. The store saves the token in its state. 5. Zustand persistence serializes that state into browser- ...[truncated 1096 chars]
Remediation
View remediation
({ user: null, token: null, login: async (email, password) => { const { user, token } = await authAPI.login(email, password); set({ user, token }); }, logout: () => set({ user: null, token: null }), }), { name: 'auth-storage', partialize: (state) => ({ user: state.user }), } ) ``` 4. Implement short token lifetimes, rotation, revocation, and replay detection on the server. 5. Apply a strict Content Security Policy and comprehensive output encoding to reduce XSS exposure. 6. Minimize same-origin third-party scripts and protect the dependency supply chain. 7. Update the reference documentation to explicitly warn readers not to persist bearer tokens in local storage. ]]>
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
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code clearly supports one subset of the declared description: scaffolding frontend projects for Next.js or React with TypeScript/Tailwind and optional modules. However, the declared purpose is materially broader, claiming optimization, review, bundle analysis, accessibility work, and performance-focused Next.js guidance. None of those capabilities are present in the supplied code chunk. The actual primary purpose is a filesystem-based project generator, not a multifunction frontend optimization/review skill. There is no evidence of source analysis, bundle inspection, accessibility auditing, or code review behavior.

Content

No source excerpt is available for this finding.

Unvalidated Output Injection

High
Category
Output Handling
Confidence
75% confidence
Finding

The snippet uses dangerouslySetInnerHTML, which is inherently risky because any sanitization misconfiguration, library bypass, or future relaxation of the allow-list could reintroduce XSS. Although DOMPurify is used and the example is clearly intended as a safe pattern, this still teaches a hazardous API and could become exploitable if copied without strict controls.

Content

Scanner excerpt · references/frontend_best_practices.md (reported line 748)May include surrounding context.

ALLOWED_ATTR: ['href'], });

return <div dangerouslySetInnerHTML={{ __html: sanitized }} />; }

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 · scripts/frontend_scaffolder.py (reported line 798)May include surrounding context.

python
build/

# Environment
.env
.env.local
.env.*.local

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/frontend_scaffolder.py (reported line 799)May include surrounding context.

python
# Environment
.env
.env.local
.env.*.local

# IDE

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill instructs the agent to read references and run local Python scripts, which implies file access and execution-related capability, but it does not declare any explicit tool scope such as allowed tools or permissions. That creates an authorization ambiguity where an agent may use broader file/environment access than reviewers or policy expect, increasing the chance of overreach into unintended files or contexts.

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 · references/frontend_best_practices.md (reported line 798)May include surrounding context.

tsx
// Cache indefinitely (default for static)
fetch('https://api.example.com/data');

// No cache - always fresh
fetch('https://api.example.com/data', { cache: 'no-store' });

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 · references/nextjs_optimization_guide.md (reported line 374)May include surrounding context.

tsx
// Cache indefinitely (default for static)
fetch('https://api.example.com/data');

// No cache - always fresh
fetch('https://api.example.com/data', { cache: 'no-store' });

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 · references/nextjs_optimization_guide.md (reported line 377)May include surrounding context.

tsx
// Cache indefinitely (default for static)
fetch('https://api.example.com/data');

// No cache - always fresh
fetch('https://api.example.com/data', { cache: 'no-store' });

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 · references/nextjs_optimization_guide.md (reported line 380)May include surrounding context.

tsx
// Cache indefinitely (default for static)
fetch('https://api.example.com/data');

// No cache - always fresh
fetch('https://api.example.com/data', { cache: 'no-store' });

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 · references/nextjs_optimization_guide.md (reported line 385)May include surrounding context.

tsx
// Cache indefinitely (default for static)
fetch('https://api.example.com/data');

// No cache - always fresh
fetch('https://api.example.com/data', { cache: 'no-store' });

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 · references/nextjs_optimization_guide.md (reported line 610)May include surrounding context.

md
{/* Load analytics after page is interactive */}
        <Script
          src="https://analytics.example.com/script.js"
          strategy="afterInteractive"
        />

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The Zustand example persists an authentication store containing a user object and token via the persist middleware to browser storage without any warning or safer storage guidance. In a frontend reference used for scaffolding, this can lead developers to store bearer tokens in localStorage, increasing exposure to token theft through XSS, browser extensions, shared-device access, or other client-side compromise.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example sets <html lang="en">, which enforces a specific language/locale in the rendered document. The guide does not mention that this is only illustrative, provide alternatives, or note when a different locale should be used, so it can normalize a fixed-language default without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code performs multiple filesystem writes via write_text() and creates directories via mkdir(), but it does not present any confirmation prompt or explicit caution that existing files may be created or overwritten. Although the script's purpose is generation, the user-facing help text and module docstring do not clearly warn that running it will directly modify files on disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code embeds subsets: ['latin'] and <html lang="en"> into generated frontend files, which forces English/Latin defaults in the scaffolded output. The skill does not offer a language/locale option or document that this is intentionally limited to English-only projects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The formatDate helper uses new Intl.DateTimeFormat('en-US', ...), which bakes a specific locale into all generated projects. This is a natural-language/locale policy issue because users are not given any choice or warning about the forced locale behavior.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/frontend_scaffolder.py:380