mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-17 00:46:53 +08:00
Three defense-in-depth fixes around untrusted input flowing to subprocess execution:
1. **Control-pane HTTP server (scripts/lib/control-pane/server.js)**
The local control-pane API binds to 127.0.0.1 but had no Host or Origin
validation, so a DNS-rebinding attack from a malicious website could pivot
into the loopback endpoints — including POST /api/actions/:id, which spawns
'cargo run -- graph ...' with caller-supplied query strings. Add a hostname
allowlist (loopback variants plus the explicitly configured --host) and
reject mismatched Host (421) or non-loopback Origin (403) before any route
handler runs.
2. **OpenCode git-summary tool (.opencode/tools/git-summary.ts)**
The tool was building 'git diff ${baseBranch}...HEAD --stat' with execSync
and a raw model-supplied baseBranch string. Switch run() to execFileSync
with an args array (no shell), validate baseBranch against a conservative
git-ref allowlist (rejects shell metacharacters, leading -, embedded ..),
and clamp the depth arg to a small positive integer before interpolating
into 'git log --oneline -<N>'.
3. **Reusable test workflow (.github/workflows/reusable-test.yml)**
The 'Install dependencies' step interpolated ${{ inputs.package-manager }}
directly into a bash 'case' and into an echo, so a downstream caller that
forwarded attacker-controllable input could inject into the runner. Move
the input into a PACKAGE_MANAGER env var and reference $PACKAGE_MANAGER
inside the script per the GitHub script-injection guidance.
Detected by Aeon + semgrep p/security-audit (host check via threat-model
manual-review axis; git-summary via detect-child-process; workflow via
run-shell-injection).
Verification: node tests/run-all.js — 2686/2687 pre-existing tests pass; the
one failure (observe.sh legacy output fallback) reproduces on main without
this branch applied. Added 2 new control-pane tests covering the allowlist
classifier and the DNS-rebinding-gate behavior end-to-end.
---
Filed by [Aeon](https://github.com/aaronjmars/aeon-aaron).
Co-authored-by: aeonframework <aeon@aaronjmars.com>
99 lines
3.3 KiB
YAML
99 lines
3.3 KiB
YAML
name: Reusable Test Workflow
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
os:
|
|
description: 'Operating system'
|
|
required: false
|
|
type: string
|
|
default: 'ubuntu-latest'
|
|
node-version:
|
|
description: 'Node.js version'
|
|
required: false
|
|
type: string
|
|
default: '20.x'
|
|
package-manager:
|
|
description: 'Package manager to use'
|
|
required: false
|
|
type: string
|
|
default: 'npm'
|
|
|
|
jobs:
|
|
test:
|
|
name: Test
|
|
runs-on: ${{ inputs.os }}
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: ${{ inputs.node-version }}
|
|
|
|
- name: Setup pnpm
|
|
if: inputs.package-manager == 'pnpm' && inputs.node-version != '18.x'
|
|
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
|
with:
|
|
# Keep an explicit pnpm major because this repo's packageManager is Yarn.
|
|
version: 10
|
|
|
|
- name: Setup pnpm (via Corepack)
|
|
if: inputs.package-manager == 'pnpm' && inputs.node-version == '18.x'
|
|
shell: bash
|
|
run: |
|
|
corepack enable
|
|
corepack prepare pnpm@9 --activate
|
|
|
|
- name: Setup Yarn (via Corepack)
|
|
if: inputs.package-manager == 'yarn'
|
|
shell: bash
|
|
run: |
|
|
corepack enable
|
|
corepack prepare yarn@stable --activate
|
|
|
|
- name: Setup Bun
|
|
if: inputs.package-manager == 'bun'
|
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
|
|
|
# COREPACK_ENABLE_STRICT=0 allows pnpm to install even though
|
|
# package.json declares "packageManager": "yarn@..."
|
|
- name: Install dependencies
|
|
shell: bash
|
|
env:
|
|
COREPACK_ENABLE_STRICT: '0'
|
|
npm_config_ignore_scripts: 'true'
|
|
YARN_ENABLE_SCRIPTS: 'false'
|
|
PACKAGE_MANAGER: ${{ inputs.package-manager }}
|
|
run: |
|
|
case "$PACKAGE_MANAGER" in
|
|
npm) npm ci --ignore-scripts ;;
|
|
# pnpm v10 can fail CI on ignored native build scripts
|
|
# (for example msgpackr-extract) even though this repo is Yarn-native
|
|
# and pnpm is only exercised here as a compatibility lane.
|
|
pnpm) pnpm install --ignore-scripts --config.strict-dep-builds=false --no-frozen-lockfile ;;
|
|
# Yarn Berry (v4+) removed --ignore-engines; engine checking is no longer a core feature
|
|
yarn) yarn install --mode=skip-build ;;
|
|
bun) bun install --ignore-scripts ;;
|
|
*) echo "Unsupported package manager: $PACKAGE_MANAGER" && exit 1 ;;
|
|
esac
|
|
|
|
- name: Run tests
|
|
run: node tests/run-all.js
|
|
env:
|
|
CLAUDE_CODE_PACKAGE_MANAGER: ${{ inputs.package-manager }}
|
|
|
|
- name: Upload test artifacts
|
|
if: failure()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: test-results-${{ inputs.os }}-node${{ inputs.node-version }}-${{ inputs.package-manager }}
|
|
path: |
|
|
tests/
|
|
!tests/node_modules/
|