mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
fix: yarn proxy mode proxy environment injection (#320)
This commit is contained in:
@@ -277,6 +277,47 @@ jobs:
|
|||||||
test -d node_modules/lodash
|
test -d node_modules/lodash
|
||||||
cd .. && rm -rf bun-test
|
cd .. && rm -rf bun-test
|
||||||
|
|
||||||
|
# Runs before the classic-yarn step so corepack's Berry shim stays the `yarn`
|
||||||
|
# on PATH (the later `npm install -g yarn@1.22.22` would shadow it).
|
||||||
|
- name: Test safedep-test-pkg is Blocked using Yarn (Berry) Proxy mode
|
||||||
|
env:
|
||||||
|
COREPACK_ENABLE_DOWNLOAD_PROMPT: "0"
|
||||||
|
YARN_NODE_LINKER: node-modules
|
||||||
|
YARN_ENABLE_HARDENED_MODE: "0"
|
||||||
|
# CI=true would enable immutable installs and fail before the proxy can block.
|
||||||
|
YARN_ENABLE_IMMUTABLE_INSTALLS: "false"
|
||||||
|
run: |
|
||||||
|
echo "Testing that safedep-test-pkg is blocked with Yarn Berry in proxy mode..."
|
||||||
|
YARN_BERRY_TESTDIR=$(mktemp -d) && cd "$YARN_BERRY_TESTDIR"
|
||||||
|
npm init -y
|
||||||
|
|
||||||
|
# Pin Yarn Berry without running an install (corepack use would trigger one).
|
||||||
|
npm pkg set packageManager=yarn@4.16.0
|
||||||
|
yarn --version
|
||||||
|
|
||||||
|
# A non-zero exit alone is not enough — yarn could fail for unrelated
|
||||||
|
# reasons (setup, network, CA trust) and falsely pass. Require PMG's
|
||||||
|
# malware block signal in the output.
|
||||||
|
if output=$(pmg yarn add safedep-test-pkg@0.1.3 2>&1); then
|
||||||
|
echo "$output"
|
||||||
|
echo "ERROR: safedep-test-pkg was not blocked with Yarn Berry!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$output"
|
||||||
|
if ! echo "$output" | grep -q "Malicious package blocked"; then
|
||||||
|
echo "ERROR: yarn add failed, but not due to a PMG malware block"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "SUCCESS: safedep-test-pkg correctly blocked with Yarn Berry"
|
||||||
|
|
||||||
|
if [ -d "node_modules/safedep-test-pkg" ]; then
|
||||||
|
echo "ERROR: safedep-test-pkg found in node_modules!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "SUCCESS: safedep-test-pkg not present in node_modules"
|
||||||
|
fi
|
||||||
|
cd - && rm -rf "$YARN_BERRY_TESTDIR"
|
||||||
|
|
||||||
- name: Test Yarn - Single Package & Manifest
|
- name: Test Yarn - Single Package & Manifest
|
||||||
run: |
|
run: |
|
||||||
echo "Testing Yarn single package installation..."
|
echo "Testing Yarn single package installation..."
|
||||||
|
|||||||
@@ -423,6 +423,9 @@ func (f *proxyFlow) setupEnvForProxy(proxyAddr, caCertPath string) []string {
|
|||||||
fmt.Sprintf("HTTPS_PROXY=%s", proxyURL),
|
fmt.Sprintf("HTTPS_PROXY=%s", proxyURL),
|
||||||
fmt.Sprintf("NO_PROXY=%s", noProxyList),
|
fmt.Sprintf("NO_PROXY=%s", noProxyList),
|
||||||
fmt.Sprintf("NODE_EXTRA_CA_CERTS=%s", caCertPath),
|
fmt.Sprintf("NODE_EXTRA_CA_CERTS=%s", caCertPath),
|
||||||
|
fmt.Sprintf("YARN_HTTP_PROXY=%s", proxyURL),
|
||||||
|
fmt.Sprintf("YARN_HTTPS_PROXY=%s", proxyURL),
|
||||||
|
fmt.Sprintf("YARN_HTTPS_CA_FILE_PATH=%s", caCertPath),
|
||||||
fmt.Sprintf("http_proxy=%s", proxyURL),
|
fmt.Sprintf("http_proxy=%s", proxyURL),
|
||||||
fmt.Sprintf("https_proxy=%s", proxyURL),
|
fmt.Sprintf("https_proxy=%s", proxyURL),
|
||||||
fmt.Sprintf("no_proxy=%s", noProxyList),
|
fmt.Sprintf("no_proxy=%s", noProxyList),
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package flows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func envToMap(env []string) map[string]string {
|
||||||
|
m := make(map[string]string, len(env))
|
||||||
|
for _, e := range env {
|
||||||
|
k, v, ok := strings.Cut(e, "=")
|
||||||
|
if ok {
|
||||||
|
m[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestSetupEnvForProxyConfiguresYarn proves the root cause of #319: yarn Berry
|
||||||
|
// (yarn 2+) ignores the standard HTTP_PROXY/HTTPS_PROXY env vars and only honors
|
||||||
|
// its own config, which can be set via YARN_* env overrides. Without these,
|
||||||
|
// yarn bypasses the MITM proxy entirely and no packages are analyzed.
|
||||||
|
func TestSetupEnvForProxyConfiguresYarn(t *testing.T) {
|
||||||
|
f := &proxyFlow{}
|
||||||
|
const proxyAddr = "127.0.0.1:54321"
|
||||||
|
const caCertPath = "/tmp/pmg-ca-cert.pem"
|
||||||
|
|
||||||
|
env := envToMap(f.setupEnvForProxy(proxyAddr, caCertPath))
|
||||||
|
|
||||||
|
proxyURL := "http://" + proxyAddr
|
||||||
|
|
||||||
|
assert.Equal(t, proxyURL, env["YARN_HTTP_PROXY"],
|
||||||
|
"yarn ignores HTTP_PROXY; YARN_HTTP_PROXY is required to route yarn through the proxy")
|
||||||
|
assert.Equal(t, proxyURL, env["YARN_HTTPS_PROXY"],
|
||||||
|
"yarn ignores HTTPS_PROXY; YARN_HTTPS_PROXY is required to route yarn through the proxy")
|
||||||
|
assert.Equal(t, caCertPath, env["YARN_HTTPS_CA_FILE_PATH"],
|
||||||
|
"yarn ignores NODE_EXTRA_CA_CERTS; YARN_HTTPS_CA_FILE_PATH is required to trust the MITM CA")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user