Back to skill

Security audit

HTML 转桌面应用

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for packaging local web apps, but its macOS fallback packager can bundle too much project data and trusts a supplied Electron archive without enforcing integrity checks.

Review this skill before installing if you may package projects containing secrets. Prefer the normal electron-builder path with an explicit files allowlist, inspect the final bundle contents before distribution, and only use the cached macOS fallback with a verified Electron archive that exactly matches the intended version and architecture.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/package_cached_electron_macos.sh:28
Finding

Overly Broad Project Copy Can Expose Sensitive Files in Packaged Applications

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/package_cached_electron_macos.sh:9
Finding

Cached Electron Runtime Is Not Verified for Integrity, Version, or Architecture

Content
View full analysis
&2; exit 1; } [[ -f "$electron_zip" ]] || { echo "Electron archive not found: $electron_zip" >&2; exit 1; } [[ -f "$project_dir/package.json" ]] || { echo "Missing package.json in $project_dir" >&2; exit 1; } [[ -f "$project_dir/main.cjs" || -f "$project_dir/main.js" ]] || { echo "Missing Electron main process." >&2; exit 1; } [[ ! -e "$output_app" ]] || { echo "Refusing to overwrite: $output_app" >&2; exit 1; } work_dir="$(mktemp -d)" trap 'rm -rf "$work_dir"' EXIT ditto -x -k "$electron_zip" "$work_dir" runtime_app="$work_dir/Electron.app" [[ -d "$runtime_app" ]] || { echo "Archive does not contain Electron.app." >&2; exit 1; } ``` ### Technical Analysis The script verifies only that the user-supplied archive exists and that extraction produces a directory named `Electron.app`. It does not verify: - That the archive is an authentic Electron release. - That its checksum matches a trusted release checksum. - That its version matches the Electron version locked by the project. - That its CPU architecture matches the requested artifact architecture. - That the extracted runtime has a valid, expected upstream signature before modification. Consequently, a substituted archive containing attacker-controlled native executables would satisfy the current checks. The script later applies an ad-hoc signature to the assembled application, but that operation does not establish the provenance of the original runtime. It can instead make a substituted runtime appear locally assembled and internally consistent. Version or architecture mismatches can also produce broken or unreliable artifacts, particularly when native modules are involved. ### Attack Path 1. An attacker with a ...[truncated 1407 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The supplied code chunk is a shell test script, not packaging logic. It creates temporary sample projects, writes HTML/CSS/JS and Electron-related files, calls inspect_web_app.sh on them, and asserts expected analysis results with grep. It does not package an existing site into an Electron application, build installers, or emit macOS/Windows app artifacts. Its primary purpose is validating inspection behavior, including identifying static multi-page apps, local storage usage, and remote backend references. That is materially different from the declared packaging purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description and usage examples are entirely in Chinese, including the invocation phrasing, with no indication that other languages are supported or that Chinese is required for a justified regional purpose. This can violate language/locale policy because it implicitly constrains users to a specific language without opt-in.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 39)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 40)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 41)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 42)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 43)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 44)May include surrounding context.

sh
cp "$project_dir/build/icon.icns" "$output_app/Contents/Resources/electron.icns"
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 40)May include surrounding context.

sh
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $app_version" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 41)May include surrounding context.

sh
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $app_version" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 42)May include surrounding context.

sh
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $app_version" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 43)May include surrounding context.

sh
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $app_version" "$plist"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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.

Content

Scanner excerpt · scripts/package_cached_electron_macos.sh (reported line 44)May include surrounding context.

sh
fi

plist="$output_app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName $app_name" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $app_id" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $app_version" "$plist"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/run_fixture_checks.sh (reported line 22)May include surrounding context.

sh
printf '%s\n' "const { app } = require('electron'); const db = app.getPath('userData') + '/notes.json';" > "$storage_dir/main.cjs"
printf '%s\n' "contextBridge.exposeInMainWorld('notes', { list: () => ipcRenderer.invoke('notes:list') });" > "$storage_dir/preload.cjs"

printf '%s\n' '<script>fetch("https://api.example.test/notes")</script>' > "$remote_dir/index.html"

static_out="$($skill_dir/scripts/inspect_web_app.sh "$static_dir")"
storage_out="$($skill_dir/scripts/inspect_web_app.sh "$storage_dir")"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest presents the skill name and description in Chinese while the default prompt is hard-coded in English. This creates a locale/language policy concern because the skill appears to force an English interaction path without explicit user opt-in or a documented language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.