Skip to content

fix(security): harden run.js binary path validation; annotate install.js fs_write#12

Draft
geekjourneyx with Copilot wants to merge 111 commits into
mainfrom
copilot/fix-shell-exec-in-run-script
Draft

fix(security): harden run.js binary path validation; annotate install.js fs_write#12
geekjourneyx with Copilot wants to merge 111 commits into
mainfrom
copilot/fix-shell-exec-in-run-script

Conversation

Copilot AI commented May 8, 2026

Copy link
Copy Markdown

An automated security scan flagged execFileSync in run.js:18 as shell_exec and fs.createWriteStream in install.js:104 as a risky fs_write. Both are false positives, but the code can be made more explicitly safe.

Changes

  • scripts/run.js

    • Replace bare path.join with path.resolve for an absolute, normalised binary path
    • Add a containment assertion using path.relative() (cross-platform; avoids slash-direction ambiguity on Windows): if the resolved path escapes bin/, the process exits before execution
    • Inline comment clarifying execFileSyncshell_exec: no shell is invoked, args are passed as an array
  • scripts/install.js

    • Inline comment on fs.createWriteStream documenting that destinationPath is always inside a mkdtempSync temp dir and assetName comes from a hardcoded platform whitelist — not user input
// Before
const binaryPath = path.join(__dirname, "..", "bin", `md2wechat${ext}`);

// After — explicit boundary; path.relative() is cross-platform safe
const binDir = path.resolve(path.join(__dirname, "..", "bin"));
const binaryPath = path.resolve(path.join(binDir, `md2wechat${ext}`));
const rel = path.relative(binDir, binaryPath);
if (rel.startsWith("..") || path.isAbsolute(rel)) {
  console.error("Internal error: binary path is outside the expected bin/ directory.");
  process.exit(1);
}

geekjourneyx and others added 30 commits February 6, 2026 15:32
- Add 38 API themes (v2.0): Minimal, Focus, Elegant, Bold series
- Add background_type parameter: default/grid/none
- Add Google Gemini image provider (official SDK)
- Add OpenRouter image provider
- Update documentation with new themes and parameters
- Add theme version tracking (v1.0 vs v2.0)
- fix: IsAIRequest/ExtractAIRequest 字符串切片魔法数字 bug(始终返回 false)
- fix: .claude-plugin/marketplace.json source 字段修正为 "./"
- refactor: 引入 aiModePrefix 常量消除魔法数字
geekjourneyx and others added 20 commits April 27, 2026 00:21
…lic SKILL.md

- SKILL.md (both): mark layout modules as API-mode-only with blockquote
- SKILL.md (both): add gentle AI→API nudge in Agent Rules (no URL, no interruption)
- SKILL.md (both): add API access note after layout decision flow (no URL)
- AGENTS.md: add layout API-only constraint note with md2wechat.cn contact URL
- .github/copilot-instructions.md: add layout API-only constraint with contact URL

URL https://www.md2wechat.cn kept only in internal dev docs (AGENTS.md, copilot-instructions.md).
Public skill files use 联系作者咨询 without exposing the URL.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…v2.1.0

- docs/LAYOUT.md: 全新保姆级高级排版模块使用教程(43 个模块完整覆盖)
- assets/readme-header.gif: Editorial CLI 风格头图动画(900×400,7.2s 循环)
- README.md: 替换静态封面为动态头图 GIF
- CHANGELOG.md: v2.1.0 补充 Fixed(YAML 语义)、Changed(SKILL API 提示)两节
- docs/QUICKSTART.md: 添加 LAYOUT.md 阅读顺序,版本号 v2.1.0
- docs/FAQ.md / INSTALL.md / USAGE.md: 版本号 v2.1.0
- docs/README.md: 能力专题新增 LAYOUT.md 链接
- .gitignore: 新增 .cache/ 和 docs/superpowers/

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- New hero tagline: 专为 AI 时代设计的公众号创作工作台
- API unlock banner elevated to position 2 (after hero)
- First-principles comparison table: md2wechat vs other tools
- 43 layout modules section elevated with :::block syntax examples
- AI vs API contrast table with clear framing (unlock, not barrier)
- Agent discovery commands section
- Coding Agent platform table (Claude Code / Obsidian / OpenClaw)
- Unified community section (QR code + WeChat group + 打赏)
- Cut: 3 Mermaid diagrams, 5x install repetitions, 200-line quality
  scoring system, Windows PowerShell details, npm mirror workaround,
  ModelScope flowchart, full theme color tables, directory tree
- Star History and zread badge preserved exactly

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
authentic bypasses base.yaml (24-pattern checklist) and uses its own
complete template. Six-dimension rules guide the output toward writing
that reads like a real person — concrete expression, stable tone, no
performative depth — rather than the subtractive 'remove AI traces' model.

Architecture: BuildPrompt checks for IntensityAuthentic first and renders
authentic.yaml directly with only the CONTENT variable. Falls back to
aggressive if the YAML is missing. gentle/medium/aggressive continue to
use base.yaml unchanged.

Usage:
  md2wechat humanize article.md --intensity authentic

ParseIntensity aliases: authentic / natural / 真实 / 自然

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…SCOVERY.md

- docs/HUMANIZE.md: new beginner-friendly tutorial covering all four
  intensity levels, --show-changes, -o, write integration, JSON/stdin
  usage, and a Q&A section distinguishing authentic vs aggressive
- skills/md2wechat/SKILL.md: add authentic example + intensity table
- platforms/openclaw/md2wechat/SKILL.md: same
- docs/DISCOVERY.md: add 'prompts show authentic' example

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…to v2.1.0 entry

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
….0 release

- unify E2E layout module list to 19 modules (matches examples/layout-e2e-test.md)
- add layout list/show/render/validate to discovery section in CLAUDE.md
- add authentic intensity level to humanizer discovery in all three files
- fix AGENTS.md duplicate platforms/openclaw entry in Release Discipline
- fix CLAUDE.md OpenClaw version check (uses @latest, not versioned release URL)
- fix CLAUDE.md 常用命令: remove gh CLI dependency (release.yml auto-creates Release)
- add docs/HUMANIZE.md to file index (CLAUDE.md) and documentation sync (all files)
- add docs/HUMANIZE.md to AGENTS.md Documentation Discipline review set
- clarify GitHub Release is auto-created by release.yml on tag push (copilot-instructions)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- wrap resp.Body.Close() in anonymous func to satisfy errcheck
- check error from buf.ReadFrom to satisfy errcheck

docs: rename '社群 & 联系' to '关于作者', add structured table with jieni.ai

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- README: Volcengine Ark ⭐主推荐, ModelScope 次推荐
- OPENCLAW.md: update example config to use volcengine
- CONFIG.md: update example config to use volcengine

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Added a note about joining a WeChat group for updates and community interaction.
Removed duplicate recommendation for codesome in README.
- Replace MIT with BUSL 1.1 + custom personal use grant (中英双语)
- Personal use, learning, evaluation, non-profit: free, no auth required
- Commercial use requires prior written authorization
- Change Date: 2030-01-01 (auto-relicense to Apache 2.0)
- Explicitly prohibit rebrand/white-label and AI training data use
- Clarify WeChat Traffic Owner ad revenue is non-commercial (free)
- Add contact: skrphper@gmail.com / jieni.ai / x.com/seekjourney
- Update README badge, package.json, marketplace.json, homebrew formula
- Historical MIT versions unaffected; applies to all new versions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 2 commits May 8, 2026 17:25
…e in install.js

- Use path.resolve() for absolute normalised binary path in run.js
- Add containment assertion: binaryPath must start with binDir to prevent
  any theoretical path traversal (belt-and-suspenders; ext is platform-constant)
- Add inline comments explaining execFileSync is NOT shell_exec (no shell
  interpolation, args passed as array) — addressing scanner false positives
- Annotate install.js fs.createWriteStream call with write-path provenance
  (mkdtempSync temp dir + hardcoded platform whitelist)"

Agent-Logs-Url: https://github.com/geekjourneyx/md2wechat-skill/sessions/795588d1-013d-4fd6-8fa5-0a559be93cf6

Co-authored-by: geekjourneyx <24422856+geekjourneyx@users.noreply.github.com>
…t check

Replaces startsWith(path.sep) with path.relative()-based check as suggested
by code review. On Windows, path normalisation can produce either slash
direction, making startsWith() unreliable. path.relative() handles this
correctly on all platforms.

Agent-Logs-Url: https://github.com/geekjourneyx/md2wechat-skill/sessions/795588d1-013d-4fd6-8fa5-0a559be93cf6

Co-authored-by: geekjourneyx <24422856+geekjourneyx@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix critical shell_exec finding in run script fix(security): harden run.js binary path validation; annotate install.js fs_write May 8, 2026
Copilot AI requested a review from geekjourneyx May 8, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security scan results: 68/100 — critical shell_exec in run script

3 participants