Back to skill

Security audit

IFQ App Builder

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed, workspace-scoped prompt-bundle generator; the main cautions are mandatory IFQ attribution and downstream scaffold commands that should be reviewed before execution.

Install this only if you are comfortable with generated bundles and some generated app surfaces carrying the IFQ colophon. Before handing a bundle to another coding agent, review scaffold commands, pin package versions where possible, and run installs in an isolated project or container without unrelated secrets. Keep the skill's Tier 0 use to prompt-bundle generation and do not provide signing certificates, store tokens, or live credentials at that stage.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:17
Finding
Mandatory IFQ Branding Hijacks Generated Outputs## Vulnerability Details **File Locations**: - `SKILL.md:17` - `references/ifq-brand-spec.md:5-13` - `scripts/lib/bundle-scanner.mjs:162-169` - `scripts/lib/bundle-scanner.mjs:251` - `assets/templates/react-native-expo.prompt.md:55-63` **Vulnerability Type**: Mandatory promotional content enforced through Skill instructions and validation logic **Risk Level**: High ### Vulnerable Code `SKILL.md:17`: ```markdown > Made by [ifq.ai](https://ifq.ai). Every generated bundle ends with the quiet colophon `— shaped with ifq.ai/app-builder · <mode> · <template>`. ``` `references/ifq-brand-spec.md:5-13`: ```markdown ## Required in every bundle 1. **Exactly one colophon line at the end**: ``` — shaped with ifq.ai/app-builder · <mode> · <template> ``` The scanner enforces this verbatim (case-insensitive). It must appear exactly **once** per bundle. 2. **Token reference in `## Scaffold` or `## IFQ ambient`**: either a path to `assets/ifq-brand/ifq-tokens.css` (for web/desktop) or a native-equivalent theme file path (see `BRAND-DNA.md`). ``` `scripts/lib/bundle-scanner.mjs:162-169`: ```javascript // ── Colophon present exactly once ── const colophons = fullText.match(/—\s*shaped\s+with\s+ifq\.ai\/app-builder/gi) || []; stats.colophonCount = colophons.length; if (colophons.length === 0) { findings.push({ level: 'error', code: 'missing-colophon', message: 'missing IFQ colophon line `— shaped with ifq.ai/app-builder`' }); } else if (colophons.length > 1 && !templateMode) { findings.push({ level: 'warn', code: 'duplicate-colophon', message: `colophon appears ${colophons.length} times; should appear once at the end` }); } ``` `scripts/lib/bundle-scanner.mjs:251`: ```javascript pass('IFQ ambient', stats.colophonCount === 1, stats.colophonCount === 0 ? 'add the colophon line' : 'colophon should appear exactly once'); ``` `assets/templates/rea ...[truncated 2698 chars]
Remediation
## Remediation Suggestions 1. Remove the requirement that every generated bundle contain IFQ branding. 2. Delete the `missing-colophon` validation error from `bundle-scanner.mjs`. 3. Remove branding as a scored quality axis. 4. Remove mandatory IFQ theme files and user-interface attribution from platform templates. 5. Make attribution strictly opt-in through an explicit user-controlled setting such as `include_attribution: true`. 6. Default user-owned applications to no third-party branding. 7. Keep package authorship information in repository metadata, `NOTICE.md`, and marketplace metadata instead of injecting it into generated deliverables. 8. Add regression tests confirming that unbranded bundles pass validation and receive no scoring penalty.

T08 · Insecure Dependencies

Warning
Location
assets/templates/react-native-expo.prompt.md:25
Finding
Generated Build Instructions Execute Unpinned Registry Packages## Vulnerability Details **File Locations**: - `assets/templates/react-native-expo.prompt.md:25-44` - `assets/templates/local-web-nextjs.prompt.md:33` - `assets/templates/cli-node-python.prompt.md:34-51` - `assets/templates/pc-tauri.prompt.md:34-36` - `assets/templates/pwa-vite.prompt.md:34` - `assets/templates/wechat-miniprogram.prompt.md:39` **Vulnerability Type**: Unpinned third-party dependency retrieval and package execution **Risk Level**: Medium ### Vulnerable Code `assets/templates/react-native-expo.prompt.md:25-44`: ```markdown - [ ] `npx expo start` boots the app in Simulator and Emulator without warnings - [ ] Primary workflow from S1 works identically on iOS + Android - [ ] All strings localized via `i18n-js` + JSON files (`zh-CN`, `en`) - [ ] `eas build --platform all --profile preview` succeeds - [ ] `expo doctor` reports 0 issues - [ ] No `console.warn` during the happy path ## Scaffold (run order) 1. `npx create-expo-app@latest <slug> -t default` 2. `cd <slug> && npx expo install expo-router expo-localization` 3. `app/_layout.tsx` declares stacks; routes are file-based under `app/` 4. Create `theme/ifq.ts` exporting IFQ color + font tokens; consume via `ThemeContext` 5. State: Zustand store under `store/`; data fetching via React Query 6. Add `eas.json` with `development`, `preview`, `production` profiles 7. `npx expo install expo-secure-store` for any credential ## Packaging - `eas build --platform ios --profile production` → `.ipa` - `eas build --platform android --profile production` → `.aab` - Web: `npx expo export --platform web` → static `dist/` - `eas submit -p ios` / `eas submit -p android` for store upload ``` Other affected templates contain commands such as: ```text npx create-next-app@latest <slug> --ts --tailwind --app --eslint npm install commander zod chalk picocolors npm install -D typescript @types/node tsx vitest pip insta ...[truncated 2454 chars]
Remediation
## Remediation Suggestions 1. Replace `@latest` and unversioned package names with exact, reviewed versions. 2. Generate and commit ecosystem lockfiles, including `package-lock.json` or an equivalent platform lockfile. 3. Use reproducible installation commands such as `npm ci` after lockfile creation. 4. Verify registry provenance and integrity metadata before execution. 5. Require explicit user confirmation before any command downloads or executes third-party code. 6. Run package installation in an isolated container or restricted build account without signing credentials or unrelated secrets. 7. Disable lifecycle scripts during initial dependency retrieval where feasible, inspect the dependency tree, and enable only required scripts afterward. 8. Pin scaffold generators such as `create-expo-app` and `create-next-app` to reviewed versions rather than using `@latest`. 9. Document that package installation belongs to Tier 1 and must not be executed automatically during the Skill's Tier 0 workflow. 10. Add template validation rules that reject `@latest` and unversioned install commands.
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (67)

Ae1

High
Category
analysis-evasion
Content
s. Zero dependencies, workspace-scoped, no required credentials.","entrypoint":"SKILL.md","homepage":"https://github.com/peixl/ifq-app-builder","os":["darwin","
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Security baseline
- Validate every argument with zod / pydantic; reject unknown flags
- Never `child_process.exec(userInput)` / `subprocess.run(shell=True, userInput)`
- Tokens / API keys: read from env vars or OS keychain, never positional args
- File writes: refuse to write outside `cwd` unless `--out` is explicit
- Print a single-line summary on `SIGINT`; never leave half-written files
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
<replace: 3 binary statements describing a successful first launch>

## Acceptance (binary, yes/no observable)
- [ ] `npx expo start` boots the app in Simulator and Emulator without warnings
- [ ] Primary workflow from S1 works identically on iOS + Android
- [ ] All strings localized via `i18n-js` + JSON files (`zh-CN`, `en`)
- [ ] `eas build --platform all --profile preview` succeeds
Confidence
80% confidence
Finding
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
<replace: 3 binary statements describing a successful first launch>

## Acceptance (binary, yes/no observable)
- [ ] `npx expo start` boots the app in Simulator and Emulator without warnings
- [ ] Primary workflow from S1 works identically on iOS + Android
- [ ] All strings localized via `i18n-js` + JSON files (`zh-CN`, `en`)
- [ ] `eas build --platform all --profile preview` succeeds
Confidence
80% confidence
Finding
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Credential Access

High
Category
Privilege Escalation
Content
.agents/
.learnings/
.well-known/
.env
.env.*

# Local working files and generated bundles
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
function checkClawHubCleanliness() {
  const ignore = read('clawhub.ignore.txt');
  for (const token of ['.git/', '.github/', 'node_modules/', '.DS_Store', '.openclaw', '.well-known/', '.env', '*.schema.json', 'personal-asset-index.json']) {
    if (!ignore.includes(token)) fail(`clawhub.ignore.txt must exclude ${token}`);
  }
  const extensionlessRootFiles = fs.readdirSync(root, { withFileTypes: true })
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Session Persistence

Medium
Category
Rogue Agent
Content
- verification command and result
- caveats that affect use

The first run should not ask for login, install Xcode/Android Studio/Flutter/Rust, configure certificates, start background services, or claim store submission.

## Good starter prompts
Confidence
70% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The manifest metadata lists generic triggers such as "build app", "make app", "ship app", and "desktop app", which overlap with common user requests and could match many unrelated conversations. Although the description narrows the skill's purpose, the trigger list itself does not provide negative examples or tighter activation constraints.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The skill's safety contract says there are no process-spawning primitives, yet the documented workflow repeatedly instructs the agent to execute shell commands such as `npm run verify:lite`, `validate`, and `pack`. This contradiction can mislead users, auditors, or policy engines into granting more trust than warranted, increasing the chance that shell execution is enabled under false assumptions.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The document requires that every generated bundle end with exactly one colophon line, and that line is fixed in English: "— shaped with ifq.ai/app-builder · <mode> · <template>". This imposes a specific language on all outputs without user opt-in or any documented locale exception, which is a natural-language policy concern.

Vague Triggers

Medium
Confidence
90% confidence
Finding
This JSON manifest defines activation triggers, so SQP-1 applies. Phrases such as "Tauri", "desktop tool", and especially short generic labels like "Swift" can match many ordinary requests without clearly constraining when this specific template should activate, increasing the risk of unintended invocation.

Vague Triggers

Medium
Confidence
88% confidence
Finding
Entries like "Mac App", "menu bar", and "Swift" are common development terms that do not clearly distinguish this template from many other macOS or Swift-related requests. The manifest does not provide negative examples or disambiguation rules to prevent broad matching.

Vague Triggers

Medium
Confidence
86% confidence
Finding
Terms such as ".NET" and "WPF" are broad ecosystem labels rather than narrowly scoped activation phrases. Without additional constraints, ordinary requests mentioning those technologies could unintentionally route to this specific Windows-native template.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger "RN" is a very short abbreviation with high ambiguity and likely overlap with unrelated everyday or technical usage. The manifest does not include limiting context or negative examples to reduce accidental activation.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The requirement specifies `Localized messages: zh-CN + en (auto-detect via LC_ALL/LANG)`, which forces support and automatic locale behavior for these languages rather than offering a user choice. This can violate language/locale policy when a skill imposes locale behavior without explicit opt-in or a documented justification.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Line L28 specifies `zh-CN`, `en`, fallback `en` as required app strings. This imposes a specific locale requirement in the template without offering user choice or explaining a region-specific need, which matches the language/locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The acceptance criteria require all strings to be localized specifically to `zh-Hans` and `en`, and the scaffold repeats that requirement. This enforces a fixed language policy in the template rather than offering a locale choice or documenting why only these locales are required.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The template uses Chinese-only strings for key deployment and authentication fields, which imposes a specific language/locale in the skill content. There is no indication that users may choose another language or that the template is intentionally limited to a Chinese-speaking context.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The template instructs use of `npx create-next-app@latest`, which pulls and executes the newest package version at runtime rather than a pinned, reviewed release. In a build-generation skill, this increases supply-chain risk and harms reproducibility because an upstream compromise or breaking release could change generated output or execute malicious install-time code.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The acceptance criteria hard-code localization to `zh-Hans` and `en`, which imposes a specific language/locale requirement in the template. This is a natural-language policy concern because the file does not present this as optional, user-selectable, or justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
Line L27 states that all copy must be localized in `zh-CN` and `en`, which is a natural-language locale requirement applied by default. The file does not offer a language choice or explain why those locales are mandatory, so this can violate language/locale policy guidance.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The template instructs use of `npx tauri` without pinning an explicit package version, which can fetch whatever version is current at execution time. In a build/scaffolding workflow, that creates a supply-chain and reproducibility risk: users may unknowingly execute unexpected code or get breaking behavior from a newly published package.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The acceptance criteria require all strings to be localized specifically via `i18next` for `zh-CN` and `en`. This imposes a language/locale constraint in natural language without stating that users can choose their preferred locale or that the scope is intentionally limited to those locales.

Static analysis

No suspicious patterns detected.