Back to skill

Security audit

React Nextjs Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a plausible React/Next.js project generator, but it asks agents to run local scripts and generate files from user-provided text without enough path, dependency, or code-injection safeguards.

Install only if you are comfortable reviewing and sandboxing generated projects. Run it in a disposable workspace, avoid using untrusted requirement documents, verify the invoked script path points to the installed artifact, and review generated files before running npm install or npm run dev.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
generator.ts:301
Finding
Arbitrary File Write Through Unsanitized Generated Paths<![CDATA[ ## Vulnerability Details **File Location**: `generator.ts:301-309` and `generator.ts:541-546` **Vulnerability Type**: Path traversal leading to arbitrary file creation or overwrite **Risk Level**: High ### Vulnerable Code ```typescript for (const page of requirements.pages) { const routePath = page.route.startsWith('/') ? page.route.slice(1) : page.route; const pageDir = routePath === '' ? pagesDir : path.join(pagesDir, ...routePath.split('/')); if (routePath !== '') { await fs.promises.mkdir(pageDir, { recursive: true }); } const pageContent = this.generatePageComponent(page, requirements, uiAnalysis); await fs.promises.writeFile(path.join(pageDir, 'page.tsx'), pageContent); } ``` A second affected write uses the component name directly: ```typescript if (requirements.components && requirements.components.length > 0) { for (const componentName of requirements.components) { const componentContent = this.generateComponent(componentName, uiAnalysis); await fs.promises.writeFile( path.join(componentsDir, `${componentName}.tsx`), componentContent ); } } ``` ### Technical Analysis Page routes and component names extracted from the user-supplied requirements document are used to construct filesystem paths without validation. Node.js `path.join()` normalizes traversal segments such as `..`; it does not guarantee that the resulting path remains under the intended output directory. The code does not reject absolute paths, traversal components, path separators, symbolic-link escapes, or platform-specific path syntax. Consequently, an attacker who controls the requirements document can cause the generator to write outside `src/app` or `src/components`. This exceeds the minimum filesystem privileges needed to generate a project because the generator should only create files beneath the selected project root. ### Attack Path 1. An attacker supplies a requirements document containing a page route such as `. ...[truncated 1048 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Permit only expected route segments and component identifiers, using a restrictive allowlist such as letters, digits, underscores, and hyphens. - Explicitly reject empty segments, `.`, `..`, absolute paths, drive-qualified paths, null bytes, and both Unix and Windows path separators where they are not required. - Resolve every destination against a canonical project root and verify containment before writing: ```typescript const root = path.resolve(projectPath); const destination = path.resolve(root, relativeDestination); if (destination !== root && !destination.startsWith(root + path.sep)) { throw new Error('Destination escapes the generated project root'); } ``` - Perform the same containment validation immediately before every `mkdir` and `writeFile`. - Consider refusing to follow symbolic links or generating inside a newly created directory whose ownership and contents are controlled by the Skill. - Use a separate validated route-to-directory conversion function rather than treating user input as a filesystem path. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
generator.ts:397
Finding
Generated TypeScript and JSX Code Injection<![CDATA[ ## Vulnerability Details **File Location**: `generator.ts:397-409`, `generator.ts:477-500`, and `generator.ts:617-627` **Vulnerability Type**: Unescaped user input interpolated into generated executable source code **Risk Level**: High ### Vulnerable Code ```typescript private generatePageComponent(page: any, requirements: any, uiAnalysis: any): string { // 根据页面需求和UI分析生成具体的页面组件 return `\ 'use client'; import React from 'react'; import { Card, Typography } from 'antd'; import MainLayout from '@/components/Layout'; const { Title, Paragraph } = Typography; export default function ${page.name}Page() { return ( <MainLayout title="${page.name}"> <div className="container mx-auto px-4 py-8"> <Card className="shadow-lg"> <Title level={2}>${page.name}</Title> <Paragraph>${page.description}</Paragraph> ``` Feature text is also inserted into generated source comments: ```typescript fetchData: async () => { set({ loading: true, error: null }); try { // TODO: Implement fetch logic for ${feature} // const response = await fetch('/api/...'); // const data = await response.json(); // set({ data, loading: false }); } catch (error) { set({ error: error.message, loading: false }); } }, ``` Component text is similarly inserted into TSX: ```typescript private generateComponent(componentName: string, uiAnalysis: any): string { return `\ import React from 'react'; import { Card, Typography } from 'antd'; const { Title, Text } = Typography; interface ${this.toPascalCase(componentName)}Props { // TODO: Define props based on requirements } const ${this.toPascalCase(componentName)}: React.FC<${this.toPascalCase(componentName)}Props> = ({}) => { return ( <Card className="shadow-md"> <Title level={4}>${componentName}</Title> ``` ### Technical Analysis Values originating in the requirements document are inserted directly into TypeScript and JSX templates. The generator does not appl ...[truncated 1919 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never concatenate untrusted requirements text directly into executable source templates. - Validate generated identifiers against TypeScript identifier rules and reject values that cannot be safely represented. - Store display text in a structured data file, serialize it with `JSON.stringify()`, and have static component code render the resulting string. - If values must be embedded in source, apply context-specific encoding separately for JavaScript strings, JSX text, comments, and identifiers. - Remove user-controlled content from generated comments because newline characters can terminate a comment and inject code. - Parse the resulting source with a TypeScript or Babel parser before writing it, and reject unexpected syntax. - Prefer an AST-based code generator over raw template interpolation. - Add tests containing quotes, backticks, braces, JSX closing tags, comment terminators, and newline characters to verify that input always remains inert data. ]]>

T08 · Insecure Dependencies

Warning
Location
create-react-app.sh:20
Finding
Execution of Mutable and Unpinned Package Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `create-react-app.sh:20-23` **Vulnerability Type**: Unsafe dependency retrieval and package-manager code execution **Risk Level**: Medium ### Vulnerable Code ```bash # 初始化Next.js项目 npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" # 安装额外依赖 npm install antd @ant-design/icons zustand ``` ### Technical Analysis The script invokes `create-next-app@latest`, which is a mutable package reference, and installs additional dependencies without exact versions or a reviewed lockfile. `npx` downloads and executes package code, while `npm install` may execute dependency lifecycle scripts. Because the resolved packages can change after the Skill has been reviewed, the actual code executed during a later invocation is not fixed by the audited package. This introduces unnecessary supply-chain exposure and makes builds non-reproducible. Network access is needed to install the declared framework dependencies, but executing mutable package versions exceeds the minimum privilege and predictability needed for project generation. ### Attack Path 1. A user invokes the Skill and its project-creation shell script. 2. `npx` contacts the configured npm registry and resolves the current package associated with the `latest` tag. 3. The package manager downloads and executes that package. 4. `npm install` resolves further mutable dependency ranges and may run lifecycle scripts. 5. If a registry account, package release, dependency, registry endpoint, or local npm configuration is compromised, attacker-controlled code executes under the invoking user's account. ### Impact Assessment Malicious package or lifecycle code can perform any operation available to the user running the script, including reading user-accessible files and environment variables, modifying the generated project or other writable files, and making outbound network connections. The vulnerability does not itself ...[truncated 174 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace `@latest` and unversioned installs with exact, reviewed package versions. - Generate and commit a lockfile for the bootstrap environment and use `npm ci` to enforce it. - Verify registry configuration and use the official registry over TLS. - Consider using `npm install --ignore-scripts` where package lifecycle scripts are not required. - Review dependency integrity hashes and update dependencies through a controlled review process. - Run package installation in a sandbox or container with restricted filesystem access, no unnecessary credentials, and constrained outbound networking. - Document all network access and obtain explicit user confirmation before downloading or executing packages. ]]>

T07 · Tool Hijacking and Spoofing

Warning
Location
OpenClaw-Skill.md:12
Finding
Execution of Scripts from Hard-Coded External Workspace Paths<![CDATA[ ## Vulnerability Details **File Location**: `OpenClaw-Skill.md:12-15` and `controller.md:5` **Vulnerability Type**: External local script substitution and execution **Risk Level**: Medium ### Vulnerable Instructions ```markdown 3. 使用 `exec` 工具运行项目生成脚本 4. 将需求文档保存到临时文件 5. 调用 `/Users/batype/.openclaw/workspace/skills/react-nextjs-generator/runner.ts` 生成项目 6. 返回生成的项目路径给用户 ``` The controller references a second external path: ```markdown 3. 调用 `/Users/batype/.openclaw/workspace/skills/react-nextjs-generator/create-react-app.sh` 创建基础项目结构 ``` ### Technical Analysis The Skill instructs the Agent to execute scripts from fixed absolute paths outside the audited artifact directory. The code at those paths is not cryptographically bound to the reviewed package and may differ from the files included in the artifact. This creates a substitution boundary: a stale installation, another local process, or a user capable of modifying the referenced workspace can replace the target file while the Skill's instructions continue to present it as the legitimate generator. The behavior also reduces portability and violates least privilege because the Skill only needs to execute its packaged generator, not an arbitrary mutable file elsewhere in a user's workspace. ### Attack Path 1. An attacker gains write access to the referenced workspace path, or a stale or unrelated installation already exists there. 2. The attacker replaces `runner.ts` or `create-react-app.sh` with malicious code. 3. A user triggers the Skill for a normal project-generation request. 4. Following the Skill instructions, the Agent invokes `exec` against the hard-coded absolute path. 5. The substituted script runs with the privileges and tool access of the Agent process. ### Impact Assessment A substituted script can execute arbitrary commands with the operating-system privileges of the Agent or user invoking the Skill. It may read accessible files and credentials, modify projects, invoke local to ...[truncated 292 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Resolve executable files relative to the installed Skill directory rather than using user-specific absolute paths. - Ensure the executed path points to the same artifact that was reviewed and installed. - Verify script integrity before execution using package signatures or trusted hashes. - Refuse to execute targets that are symbolic links, unexpectedly writable by other users, or outside the trusted Skill directory. - Pass arguments as a structured argument array rather than constructing a shell command. - Remove obsolete path references from both `OpenClaw-Skill.md` and `controller.md` so there is one authoritative invocation method. - Run the generator with only the filesystem and network permissions required for the selected output directory. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (15)

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill explicitly instructs the agent to use an execution tool to run a local script and to write user-supplied requirements to a temporary file, but it provides no safety checks, user confirmation, path restrictions, or guidance on handling untrusted input. In a skill that transforms arbitrary user documents into code generation actions, this increases the risk of unintended system modification, unsafe script invocation, or abuse of file and process access.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The entire skill description is written only in Chinese, and there is no indication that users may interact in another language or opt into this locale. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The skill documentation forces a specific language/locale by presenting all user-facing instructions in Chinese, with no indication that users may choose another language. Under the policy, language constraints should be optional or explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The entire skill content is written only in Chinese and does not indicate that language selection is optional or limited for a justified regional reason. This can violate language or locale policy when a skill implicitly forces a specific language without user opt-in.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill explicitly invokes a local shell script to create a project structure, which will modify the filesystem, but the description does not warn the user about these side effects or ask for confirmation. In an agent setting, undisclosed file-creation behavior can lead to unexpected writes, workspace pollution, or creation of files in unintended locations if the script or context is manipulated.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The script executes `npx create-next-app@latest`, which fetches and runs the latest package version from the network at generation time. Because the version is not pinned to a known-good release, future upstream changes or a compromised package publication could cause unreviewed code execution on the user's machine.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This shell script embeds natural-language and UI locale behavior into generated code by importing `zh_CN` and setting `ConfigProvider locale={zhCN}`. Because the skill does not provide an opt-in or explain that the generated project is intentionally China/Chinese-specific, it violates the policy against forcing a specific language/locale without user choice.

Intent-Code Divergence

Medium
Confidence
85% confidence
Finding
The module comment claims the generator creates a complete project based on requirement documents and UI design images. However, major generation paths such as page components, layout, and stores produce mostly static boilerplate, and the UI analysis is mocked, so the code does not actually do what the documentation claims at an intent level.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code and the generated UI include fixed Chinese-language descriptions and labels, starting with the class documentation and continuing in generated output. Under the language/locale policy, forcing a specific language without user choice is a natural-language policy violation unless the locale restriction is explicitly justified.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The docstring and inline comments say this method analyzes a UI design image and returns recognized components, layout, and color scheme. In reality, it only logs the path and returns hard-coded data, which directly contradicts the documented behavior rather than merely omitting detail.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The generated page template contains fixed Chinese labels such as "首页", "计数器示例", "增加", and "重置". Because the skill does not provide a language selection mechanism or document a justified locale restriction, it enforces a specific language on generated output.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The layout template inserts fixed Chinese navigation labels including "首页", "产品", and "关于我们". This is a language/locale policy issue because the generated artifact forces a single language and provides no user choice or explicit regional justification.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The code's comments and console messages are entirely in Chinese, including the usage text and status/error output. This imposes a specific language on users without offering a locale choice or documenting a justified region-specific constraint, which matches the language/locale policy violation criteria.

Missing User Warnings

Low
Confidence
78% confidence
Finding
This markdown file describes generating a complete React + Next.js project and creating project structure, pages, components, and configuration, but it does not warn the user that files and directories will be created or modified. For a markdown skill description, this is a user-impacting behavior affecting local project data and should be disclosed.

Intent-Code Divergence

Low
Confidence
75% confidence
Finding
The comment at L003 presents the file as a project generator script, but the implementation goes beyond file scaffolding by invoking `npx create-next-app@latest` and `npm install`, which download and execute package-defined setup logic from external registries. This is not merely omitted detail about generated files; it materially changes the operational behavior from local generation to remote package retrieval and execution.

Static analysis

No suspicious patterns detected.