Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 20
feat: add sfw input to wrap vp install with Socket Firewall Free#72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
112ee5f
feat: add sfw input to wrap vp install with Socket Firewall Free
fengmk2 fafe07a
test(ci): add test-sfw-blocks-malicious job using lodahs canary
fengmk2 c4df421
ci: limit test-sfw to ubuntu-latest, document sfw rustls TLS limitation
fengmk2 f5f2b16
feat(sfw): fall back to plain vp install on non-Linux with a warning
fengmk2 b3e3a58
chore: point sfw non-Linux warning at setup-vp tracker issue
fengmk2 4d71ec2
docs: point README sfw fallback note at setup-vp#73 tracker
fengmk2 b0bece4
docs(ci): collapse sfw-free issue references to setup-vp#73 tracker
fengmk2 f0618a4
docs: point isSfwSupported comment at setup-vp#73 tracker
fengmk2 d2ed525
test(ci): add test-sfw-package-managers covering pnpm/npm/yarn/bun
fengmk2 f13d0ba
test(ci): fix yarn job + promote bun to required
fengmk2 9fbb519
test(ci): force Yarn nodeLinker=node-modules so verify step is uniform
fengmk2 e6024b3
test(ci): merge test-sfw and test-sfw-package-managers into one matrix
fengmk2 aa92f44
ci+docs: address code-review findings on the matrix-merge diff
fengmk2 381ef2b
ci+src: handle PR #72 review comments
fengmk2 2e0144f
ci: only test latest vp release in test-sfw matrix
fengmk2 65e179d
ci: also drop alpha from test-sfw-alpine and test-sfw-blocks-malicious
fengmk2 b6a100f
ci: drop single-value version axis from sfw jobs entirely
fengmk2 c69ca6f
ci+src: fix code-review findings on commits since aa92f44
fengmk2 91936e2
feat(sfw): auto-detect pre-installed sfw + pin version + Renovate rule
fengmk2 18c1cc4
fix(sfw): hard-gate macOS/Windows before PATH detect + add negative a…
fengmk2 fbb345b
feat(sfw): cache the sfw binary via @actions/cache
fengmk2 77a3bfa
ci: add one-off verify-vp-1686-sfw workflow_dispatch
fengmk2 3f209a2
ci: switch verify-vp-1686-sfw to push-with-paths-filter trigger
fengmk2 80dd299
ci(verify): drop socketdev/action, install sfw manually from same URL…
fengmk2 b323a21
ci(verify): also exercise musl via alpine:3.23 container
fengmk2 43f7df0
ci(verify): bump pkg-pr-new target to vp PR #1703 (v0.1.23 release)
fengmk2 d34bd47
feat(sfw): bump SFW_VERSION to v1.11.0
fengmk2 2161235
test(sfw): add branch coverage for setupSfw, installSfw, isSfwSupported
fengmk2 d9921a6
feat(sfw): support macOS and Windows (vite-plus v0.1.23+)
fengmk2 a75aa97
refactor(sfw): drop cacheHit dead state; prove blocking on macOS/Windows
fengmk2 113b54c
chore(deps): vite-plus ^0.1.23; assert sfw blocks on composition path
fengmk2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,14 @@ | ||
| { | ||
| "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
| "extends": ["github>Boshen/renovate"], | ||
| "ignoreDeps": ["@void-sdk/void"] | ||
| "ignoreDeps": ["@void-sdk/void"], | ||
| "customManagers": [ | ||
| { | ||
| "customType": "regex", | ||
| "fileMatch": ["^src/install-sfw\\.ts$"], | ||
| "matchStrings": ["const SFW_VERSION = \"(?<currentValue>v[^\"]+)\";"], | ||
| "depNameTemplate": "SocketDev/sfw-free", | ||
| "datasourceTemplate": "github-releases" | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -292,6 +292,258 @@ jobs: | ||
| - name: Verify vp exec works | ||
| run: vp exec node -e "console.log('vp exec works in Alpine')" | ||
| test-sfw: | ||
| # sfw wraps vp install end-to-end on all OSes (macOS / Windows supported | ||
| # since vite-plus v0.1.23). On Linux we verify across every package | ||
| # manager vp auto-detects via lockfile (pnpm/npm/yarn/bun); macOS / Windows | ||
| # run pnpm only because the PM choice doesn't change the sfw wrap path — | ||
| # those cells exist to prove the cross-platform sfw download + wrap works. | ||
| # vp version is left at the action default (`latest`) — sfw is decoupled | ||
| # from vp's release channel. Other test jobs (test-cache-*, | ||
| # test-node-version, etc.) still cover the alpha channel for vp itself. | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest, windows-latest] | ||
| package-manager: [pnpm, npm, yarn, bun] | ||
| exclude: | ||
| # Non-Linux runs pnpm only — PM diversity adds no sfw-wrap coverage. | ||
| - { os: macos-latest, package-manager: npm } | ||
| - { os: macos-latest, package-manager: yarn } | ||
| - { os: macos-latest, package-manager: bun } | ||
| - { os: windows-latest, package-manager: npm } | ||
| - { os: windows-latest, package-manager: yarn } | ||
| - { os: windows-latest, package-manager: bun } | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 | ||
| - name: Create test project for ${{ matrix.package-manager }} | ||
| shell: bash | ||
| run: | | ||
| case "${{ matrix.package-manager }}" in | ||
| pnpm) LOCKFILE=pnpm-lock.yaml; CONTENTS='' ;; | ||
| npm) LOCKFILE=package-lock.json; CONTENTS='{"name":"test-project","lockfileVersion":3}' ;; | ||
| yarn) LOCKFILE=yarn.lock; CONTENTS='' ;; | ||
| bun) LOCKFILE=bun.lock; CONTENTS='' ;; | ||
| *) echo "Unsupported package-manager: ${{ matrix.package-manager }}" >&2; exit 1 ;; | ||
| esac | ||
| mkdir -p test-project | ||
| cd test-project | ||
| echo '{"name":"test-project","private":true,"dependencies":{"is-odd":"^3.0.1"}}' > package.json | ||
| printf '%s' "$CONTENTS" > "$LOCKFILE" | ||
| - name: Configure Yarn .yarnrc.yml (Linux + yarn only) | ||
| if: matrix.package-manager == 'yarn' && runner.os == 'Linux' | ||
| # nodeLinker=node-modules: Yarn Berry defaults to Plug'n'Play, which | ||
| # makes plain `require()` from a non-yarn-wrapped node process fail. | ||
| # enableImmutableInstalls=false: Yarn Berry auto-enables immutable | ||
| # installs under CI, which makes the bootstrap from an empty | ||
| # yarn.lock fail with YN0028. Setting it here (instead of via the | ||
| # YARN_ENABLE_IMMUTABLE_INSTALLS env var) survives any future | ||
| # env-sanitization vp might apply to spawned subprocesses. | ||
| shell: bash | ||
| run: | | ||
| { | ||
| echo "nodeLinker: node-modules" | ||
| echo "enableImmutableInstalls: false" | ||
| } > test-project/.yarnrc.yml | ||
| - name: Setup Vite+ with sfw + ${{ matrix.package-manager }} | ||
| uses: ./ | ||
| with: | ||
| sfw: true | ||
| run-install: | | ||
| - cwd: test-project | ||
| cache: false | ||
| - name: Verify sfw is on PATH | ||
| run: sfw --version | ||
| - name: Verify dependency installed via ${{ matrix.package-manager }} | ||
| working-directory: test-project | ||
| run: vp exec node -e "console.log(require('is-odd')(3))" | ||
| test-sfw-alpine: | ||
| # vp version is left at the action default (`latest`) — sfw's musl asset | ||
| # selection is decoupled from vp's release channel. | ||
| # NOTE: if this job is later re-matrixed (alpha+latest, multiple alpine | ||
| # versions, etc.), restore `strategy: { fail-fast: false }` so a flake in | ||
| # one shard doesn't cancel the others. | ||
| runs-on: ubuntu-latest | ||
| container: | ||
| image: alpine:3.23 | ||
| steps: | ||
| - name: Install Alpine dependencies | ||
| run: apk add --no-cache bash curl gcompat libstdc++ | ||
| - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 | ||
| - name: Create test project with a real dependency | ||
| run: | | ||
| mkdir -p test-project | ||
| cd test-project | ||
| echo '{"name":"test-project","private":true,"dependencies":{"is-odd":"^3.0.1"}}' > package.json | ||
| - name: Setup Vite+ with sfw (musl) | ||
| uses: ./ | ||
| with: | ||
| sfw: true | ||
| run-install: | | ||
| - cwd: test-project | ||
| cache: false | ||
| - name: Verify sfw is on PATH (musl) | ||
| run: sfw --version | ||
| - name: Verify dependency installed under sfw (musl) | ||
| working-directory: test-project | ||
| run: vp exec node -e "console.log(require('is-odd')(3))" | ||
| test-sfw-blocks-malicious: | ||
| # Verifies sfw actually intercepts a known-malicious package, not just | ||
| # that it wraps the install. Uses `lodahs` (lodash typosquat), the same | ||
| # canary SocketDev's own workflows use: | ||
| # https://github.com/SocketDev/bun-security-scanner/blob/main/.github/workflows/test.yml | ||
| # If this job ever stops blocking, either sfw is misconfigured or the | ||
| # canary itself has been delisted — swap it for another Socket-flagged | ||
| # package from https://socket.dev/blog/category/threat-research. | ||
| # vp version is left at the action default (`latest`) — sfw block behavior | ||
| # is decoupled from vp's release channel. | ||
| # Runs on all three OSes: a fail-open regression in vp/sfw's proxy or CA | ||
| # handling can be platform-specific (the #73 rustls cert-trust class of | ||
| # bug was), so each OS needs its own block assertion — benign-install | ||
| # success (the test-sfw job) is not enough proof. | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest, windows-latest] | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 | ||
| - name: Create test project with a benign dependency | ||
| shell: bash | ||
| run: | | ||
| mkdir -p test-project | ||
| cd test-project | ||
| echo '{"name":"test-project","private":true,"dependencies":{"is-odd":"^3.0.1"}}' > package.json | ||
| - name: Setup Vite+ with sfw and install benign dep | ||
| uses: ./ | ||
| with: | ||
| sfw: true | ||
| run-install: | | ||
| - cwd: test-project | ||
| cache: false | ||
| - name: Assert sfw blocks malicious package (lodahs typosquat of lodash) | ||
| shell: bash | ||
| working-directory: test-project | ||
| # Exit code alone isn't sufficient: a non-zero exit from npm 404, | ||
| # network blip, or vp crash would also produce a false positive. We | ||
| # also require the literal sfw block-line for lodahs in the combined | ||
| # output so an unrelated failure doesn't get reported as "sfw blocked | ||
| # it". The block-line format observed in CI is: | ||
| # " - blocked npm package: name: lodahs; version: ...; reason: ..." | ||
| # The banner "Protected by Socket Firewall" and the "=== Socket | ||
| # Firewall ===" header are emitted on EVERY sfw invocation, so neither | ||
| # of those is a usable marker — use the unique "blocked npm package: | ||
| # name: lodahs" line instead. | ||
| run: | | ||
| set +e | ||
| OUTPUT=$(sfw vp install lodahs 2>&1) | ||
| CODE=$? | ||
| set -e | ||
| printf '%s\n' "$OUTPUT" | ||
| if [ "$CODE" -eq 0 ]; then | ||
| echo "::error::sfw failed to block lodahs on ${{ matrix.os }} — install exited 0" | ||
| exit 1 | ||
| fi | ||
| if ! printf '%s' "$OUTPUT" | grep -qF -- "blocked npm package: name: lodahs"; then | ||
| echo "::error::sfw vp install exited $CODE on ${{ matrix.os }} but the lodahs block-line was not in the output — likely failed for a non-sfw reason (canary delisted, network blip, vp crash, or sfw output format changed). Swap the canary if Socket has delisted lodahs, or update the marker grep if sfw's block-line format changed." | ||
| exit 1 | ||
| fi | ||
| echo "OK: sfw blocked lodahs on ${{ matrix.os }} (exit $CODE, block-line found)" | ||
| test-sfw-with-socketdev-action: | ||
| # Exercises the composition path: install sfw via the upstream | ||
| # `socketdev/action@<sha>` step first, then call setup-vp with `sfw: | ||
| # true`. setup-vp should DETECT the pre-installed sfw on PATH (via | ||
| # findSfwOnPath()) and SKIP its bundled download. We assert that by | ||
| # checking $RUNNER_TEMP/sfw-bin/sfw[.exe] — the exact path | ||
| # installSfw() would have created — was NOT created. We also assert the | ||
| # composed sfw actually BLOCKS a malicious package (lodahs), so this path | ||
| # is proven to enforce, not just to be wired up. | ||
| # See README "Advanced: stricter supply chain via socketdev/action". | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 | ||
| - name: Create test project with a real dependency | ||
| shell: bash | ||
| run: | | ||
| mkdir -p test-project | ||
| cd test-project | ||
| echo '{"name":"test-project","private":true,"dependencies":{"is-odd":"^3.0.1"}}' > package.json | ||
| - name: Install sfw via socketdev/action | ||
| uses: socketdev/action@ba6de6cc0565af1f42295590380973573297e31f | ||
| with: | ||
| mode: firewall-free | ||
| - name: Setup Vite+ with sfw (composition path) | ||
| uses: ./ | ||
| id: setup-vp | ||
| with: | ||
| sfw: true | ||
| run-install: | | ||
| - cwd: test-project | ||
| cache: false | ||
| - name: Verify setup-vp used the composed sfw (no bundled download) | ||
| shell: bash | ||
| # Negative assertion: if setup-vp had downloaded its own sfw, it | ||
| # would land at $RUNNER_TEMP/sfw-bin/sfw[.exe] (per | ||
| # getSfwBinDir() in install-sfw.ts). On the composition path the | ||
| # PATH-detection branch should fire FIRST and skip the download | ||
| # entirely, so neither file should exist. | ||
| run: | | ||
| if [ -e "$RUNNER_TEMP/sfw-bin/sfw" ] || [ -e "$RUNNER_TEMP/sfw-bin/sfw.exe" ]; then | ||
| echo "::error::setup-vp downloaded its own sfw binary even though one was pre-installed via socketdev/action. The PATH-detection branch in setupSfw() regressed." | ||
| exit 1 | ||
| fi | ||
| echo "OK: setup-vp used the pre-installed sfw (no bundled download at \$RUNNER_TEMP/sfw-bin/)" | ||
| - name: Verify dependency installed under composed sfw | ||
| working-directory: test-project | ||
| run: vp exec node -e "console.log(require('is-odd')(3))" | ||
| - name: Assert composed sfw blocks malicious package (lodahs) | ||
| shell: bash | ||
| working-directory: test-project | ||
| # Proves the composition path actually enforces, not just that sfw is | ||
| # present. socketdev/action exports SFW_JSON_REPORT_PATH into the env, | ||
| # which makes sfw write its block report to JSON instead of stdout — | ||
| # we unset it here so the block-line goes to stdout, matching the | ||
| # marker check used by test-sfw-blocks-malicious. | ||
| run: | | ||
| unset SFW_JSON_REPORT_PATH | ||
| set +e | ||
| OUTPUT=$(sfw vp install lodahs 2>&1) | ||
| CODE=$? | ||
| set -e | ||
| printf '%s\n' "$OUTPUT" | ||
| if [ "$CODE" -eq 0 ]; then | ||
| echo "::error::composed sfw failed to block lodahs — install exited 0" | ||
| exit 1 | ||
| fi | ||
| if ! printf '%s' "$OUTPUT" | grep -qF -- "blocked npm package: name: lodahs"; then | ||
| echo "::error::composed sfw vp install exited $CODE but the lodahs block-line was not in the output (canary delisted, network blip, or sfw output format changed)." | ||
| exit 1 | ||
| fi | ||
| echo "OK: composed sfw blocked lodahs (exit $CODE, block-line found)" | ||
fengmk2 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.