Back to skill

Security audit

SaaS Landing Page Generator

Security checks for vulnerabilities and agentic risk

Overview

This landing-page generator has a coherent purpose, but its script can write outside the intended folder and can generate unsafe deployable pages when given untrusted product text.

Review this skill before installing or using it in automated workflows. Use only trusted product names and descriptions, choose an output directory deliberately, avoid running it in sensitive project roots, and inspect generated files before opening or deploying them. Harden the script by slugifying product names, blocking path traversal, refusing accidental overwrites, escaping generated HTML/JSX content, and pinning or bundling frontend dependencies.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
saas-landing-page.sh:54
Finding
Output Path Traversal Through Unsanitized Product and Output Values<![CDATA[ ## Vulnerability Details **File Location**: `saas-landing-page.sh`, lines 54–60 **Vulnerability Type**: Path traversal and unintended file overwrite **Risk Level**: High ### Vulnerable Code ```bash # Create output directory DIR_NAME=$(echo "$PRODUCT" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') OUTPUT_PATH="$OUTPUT_DIR/$DIR_NAME-landing" mkdir -p "$OUTPUT_PATH/components" mkdir -p "$OUTPUT_PATH/assets" ``` ### Technical Analysis The product name is converted to lowercase and spaces are replaced with hyphens, but path separators and traversal sequences such as `../` are preserved. `OUTPUT_DIR` is also accepted without validation or canonical containment checks. Although the variables are quoted, quoting only prevents shell word splitting and wildcard expansion. It does not prevent filesystem path traversal. The resulting path is subsequently used by multiple truncating redirections that create or replace `App.jsx`, `index.html`, `README.md`, and component files. This vulnerability becomes directly exploitable when product names or output options originate from an untrusted user, automated request, document, or agent-generated input. ### Attack Path 1. An attacker supplies a product name containing traversal components, such as `../../target`. 2. The transformations performed by `tr` leave the `../` components intact. 3. The script constructs a path such as `./../../target-landing`. 4. `mkdir -p` resolves that path outside the intended output directory. 5. Subsequent heredoc redirections create or truncate fixed-name files in that external directory. 6. The files are written with the privileges of the account running the generator. ### Impact Assessment An attacker can cause files to be created outside the intended generation directory. If a matching target directory already exists, fixed-name files such as `index.html`, `App.jsx`, or `README.md` may be overwritten. The vulnerability does not independently elevate privileges. Its scope is limi ...[truncated 208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Convert the product name into a strict slug using an allowlist such as lowercase ASCII letters, digits, and hyphens. - Reject empty slugs, `.` and `..`, path separators, control characters, and absolute paths. - Restrict output generation to a configured base directory. - Canonicalize both the base directory and final destination, then verify that the destination remains beneath the approved base. - Refuse to write into an existing directory unless the user explicitly authorizes replacement. - Use restrictive permissions and run the generator under a least-privileged account. Example hardening approach: ```bash BASE_DIR=$(realpath -m "${OUTPUT_DIR:-.}") DIR_NAME=$(printf '%s' "$PRODUCT" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g; s/-\{2,\}/-/g; s/^-//; s/-$//') [ -n "$DIR_NAME" ] || { echo "Invalid product name" >&2 exit 1 } OUTPUT_PATH=$(realpath -m "$BASE_DIR/${DIR_NAME}-landing") case "$OUTPUT_PATH/" in "$BASE_DIR/"*) ;; *) echo "Output path escapes the approved directory" >&2 exit 1 ;; esac ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
saas-landing-page.sh:107
Finding
sed Program Injection Through Unescaped Template Values<![CDATA[ ## Vulnerability Details **File Location**: `saas-landing-page.sh`, lines 107–109 **Vulnerability Type**: Dynamic sed-script injection **Risk Level**: Medium ### Vulnerable Code ```bash # Replace placeholders sed -i '' "s/PRODUCT_NAME/$PRODUCT/g" "$OUTPUT_PATH/components/Hero.jsx" sed -i '' "s/DESCRIPTION/$DESCRIPTION/g" "$OUTPUT_PATH/components/Hero.jsx" ``` ### Technical Analysis `PRODUCT` and `DESCRIPTION` are inserted directly into double-quoted sed programs. Sed replacement strings have their own syntax: `/` terminates the replacement, `&` expands to the matched text, backslashes alter interpretation, and embedded newlines may introduce additional sed commands. Shell quoting does not make these values safe for the sed language. A crafted value can therefore break out of the intended replacement field, modify the generated content, or introduce additional sed operations. On implementations supporting sed's `w` command, an injected sed program may write matched content to another file writable by the current user. The `sed -i ''` form is also specific to BSD/macOS sed and commonly fails under GNU sed, creating a portability and reliability problem. ### Attack Path 1. An attacker supplies a product name or description containing a sed delimiter, newline, or replacement metacharacter. 2. The shell expands that value inside the double-quoted sed argument. 3. Sed parses the expanded content as part of its program rather than exclusively as replacement data. 4. The attacker terminates the original substitution and introduces additional sed syntax. 5. The injected operations run with the filesystem permissions of the generator process. Exploitation depends on the installed sed implementation and accepted command syntax. Even where additional file-writing commands are unavailable, crafted input can reliably corrupt or abort generation. ### Impact Assessment The attacker can manipulate generated source code beyond the intended placeholder replac ...[truncated 376 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct a sed program from untrusted values. - Generate JSX through a template engine or a language that can serialize values safely. - Prefer storing product metadata as JSON and rendering it as data rather than inserting it into executable source. - If sed must be retained, escape every character meaningful in the replacement context, including backslashes, ampersands, delimiters, carriage returns, and newlines. - Use a temporary file and atomic rename instead of relying on platform-specific in-place editing. - Add tests covering `/`, `&`, backslashes, quotes, multiline input, Unicode, and control characters. A safer design is to serialize values into a JavaScript module with a JSON-aware tool and import them as ordinary data, rather than performing source-code replacement. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
saas-landing-page.sh:139
Finding
Persistent HTML and JSX Injection in Generated Landing Pages<![CDATA[ ## Vulnerability Details **File Location**: `saas-landing-page.sh`, lines 139–178 **Vulnerability Type**: Persistent HTML injection and cross-site scripting **Risk Level**: High ### Vulnerable Code ```bash else # Plain HTML version cat > "$OUTPUT_PATH/index.html" << HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>$PRODUCT - $DESCRIPTION</title> <meta name="description" content="$DESCRIPTION"> <script src="https://cdn.tailwindcss.com"></script> <style> .gradient-text { background: linear-gradient(to right, #2563eb, #9333ea); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } </style> </head> <body> <!-- Hero Section --> <section class="py-20 lg:py-32"> <div class="container mx-auto px-4 text-center"> <h1 class="text-5xl lg:text-7xl font-bold mb-6 gradient-text"> $PRODUCT </h1> <p class="text-xl text-gray-600 mb-8 max-w-2xl mx-auto"> $DESCRIPTION </p> ``` The same values are also inserted into React JSX through the unsafe replacements at lines 107–109 and into the React/Next.js HTML metadata at lines 115–119. ### Technical Analysis The product name and description are embedded directly into HTML text and attribute contexts without contextual output encoding. In particular: - HTML element content can be terminated and followed by attacker-controlled elements. - The description can terminate the quoted `content` attribute in the meta tag. - Attacker-controlled event handlers, script-capable elements, or other active markup can be introduced. - The generated React component treats inserted values as source fragments rather than safely serialized React text. This is a persistent injection vulnerability because the payload is written into generated source ...[truncated 1167 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Apply context-specific encoding rather than one generic sanitization operation. - HTML-escape product and description values used as text. - Attribute-escape values used inside quoted HTML attributes. - For React, serialize values as JavaScript string literals or load them from JSON instead of injecting them into JSX source. - Avoid allowing user input to become raw markup. - Add a restrictive Content Security Policy that disallows inline script and limits script origins. - Validate generated files before deployment and add automated tests using payloads containing quotes, angle brackets, event handlers, and closing tags. - Consider limiting accepted product metadata to reasonable character sets and lengths as defense in depth, while retaining contextual output encoding as the primary control. For HTML generation, use a template system with automatic escaping enabled. For React generation, create a data file such as: ```json { "product": "Safely serialized product name", "description": "Safely serialized description" } ``` Then render those values as React text nodes rather than source code. ]]>

T08 · Insecure Dependencies

Warning
Location
saas-landing-page.sh:120
Finding
Generated Pages Execute Unpinned Third-Party JavaScript<![CDATA[ ## Vulnerability Details **File Location**: `saas-landing-page.sh`, lines 120–127 **Vulnerability Type**: Insecure remote dependencies and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```html <script src="https://cdn.tailwindcss.com"></script> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react@18/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> ``` The Tailwind CDN script is also included in the plain HTML output at line 143. ### Technical Analysis The generated pages execute JavaScript directly from public CDNs at runtime. Several URLs do not specify exact immutable versions: - Tailwind uses a moving CDN endpoint. - React and ReactDOM specify only the major version. - Babel has no version pin. None of the script elements includes a Subresource Integrity hash. Consequently, the code reviewed at generation time is not necessarily the code later executed by visitors. A CDN compromise, upstream account compromise, malicious release, or mutable-tag change could alter the delivered script. The generated page also uses development and browser-side compilation dependencies that are inappropriate for a hardened production deployment. ### Attack Path 1. The generated landing page is deployed without replacing the CDN references. 2. A visitor loads the page. 3. The browser requests JavaScript from the configured third-party CDN domains. 4. The CDN or mutable upstream version supplies modified content. 5. The browser executes that content in the landing page's origin context. 6. The modified dependency can access the same page data and browser capabilities as first-party JavaScript. This path depends on an upstream or delivery-channel compromise or an unsafe mutable release, rather than direct control of the generator input. ### Impact Assessment A c ...[truncated 523 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Bundle audited production dependencies locally during a controlled build. - Pin every package to an exact version and commit the package-manager lockfile. - Replace browser-side Babel and React development builds with compiled, minified production output. - Perform dependency vulnerability and provenance scanning in the build pipeline. - If external scripts are unavoidable, use immutable versioned URLs and Subresource Integrity hashes with `crossorigin="anonymous"`. - Deploy a restrictive Content Security Policy that permits scripts only from required locations and avoids `unsafe-inline` and `unsafe-eval`. - Document the network dependencies accurately rather than describing the generated output as dependency-free. - Establish a regular process for reviewing and updating pinned dependency versions. ]]>
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The manifest description is written as an instruction that the skill generates landing pages, and all surrounding user-facing documentation is exclusively in Chinese with no indication that users can choose another language or locale. This creates a language/locale policy concern because the skill appears to impose a specific language experience without opt-in or justification.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The manifest description is written as an instruction/promise to generate the landing page in Chinese ('生成专业 SaaS Landing Page'). This can indicate a fixed language/locale expectation without offering the user a choice, which matches the policy concern for language constraints lacking opt-in.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code creates directories and later writes several files into the computed output path, which affects the user's filesystem. Although it prints progress messages, it does not disclose the risk of overwriting existing generated content or warn before modifying files.

Static analysis

No suspicious patterns detected.