Dependency Proxy with Malicious Package Firewall
DevGuard includes a built-in dependency proxy that acts as a protective layer between your development environment and public package registries. It helps prevent supply chain attacks by blocking malicious packages before they reach your systems.
Overview
The dependency proxy provides:
- Malicious Package Detection: Automatically blocks packages flagged in the OSSF malicious packages database (https://github.com/ossf/malicious-packages)
- Multiple Ecosystems: Support for npm, Go modules, and PyPI packages
- Caching: Speeds up package installations by caching frequently used packages
- Integrity Verification: SHA256 checksums ensure cached packages haven’t been tampered with
- Security Metrics: Prometheus metrics track blocked packages and proxy usage
Supported Ecosystems
NPM (Node.js)
- Registry URL:
http://localhost:8080/api/v1/dependency-proxy/npm - Configuration: Set in
.npmrcfile
Go Modules
- Registry URL:
http://localhost:8080/api/v1/dependency-proxy/go - Configuration: Set via
GOPROXYenvironment variable
PyPI (Python)
- Registry URL:
http://localhost:8080/api/v1/dependency-proxy/pypi/simple - Configuration: Set via
pip.confor environment variables
How It Works
- Request Interception: When you install a package, the proxy intercepts the request
- Database Check: The package is checked against the malicious packages database
- Blocking: If flagged as malicious, the request is blocked and logged
- Caching: Safe packages are cached with integrity verification
- Metrics: All blocked attempts are recorded in Prometheus metrics
Configuration
NPM
Create or edit .npmrc in your project directory:
registry=http://localhost:8080/api/v1/dependency-proxy/npm
strict-ssl=false # only for local testing; use true in productionThen install packages normally:
npm install lodashGo Modules
Set the GOPROXY environment variable:
export GOPROXY="http://localhost:8080/api/v1/dependency-proxy/go"
go get github.com/example/packagePyPI
Create or edit pip.conf:
[global]
index-url = http://localhost:8080/api/v1/dependency-proxy/pypi/simple
trusted-host = localhostOr use environment variables:
export PIP_INDEX_URL="http://localhost:8080/api/v1/dependency-proxy/pypi/simple"
export PIP_TRUSTED_HOST="localhost"
pip install requestsSecurity Features
Malicious Package Database
The proxy uses the OSSF Malicious Packages dataset, which contains:
- Known malicious packages across multiple ecosystems
- Typosquatting packages
- Packages with malicious code injection
- Compromised package versions
The database is automatically updated every 2 hours to ensure the latest threat intelligence.
Initialization Protection
To prevent cache poisoning attacks, the proxy blocks all requests until the malicious package database is fully loaded. This ensures:
- No malicious packages can be cached during the initialization window
- The system is secure by default
- Users receive a clear “Service is initializing” message if they try to install packages too early
Integrity Verification
All cached packages are protected with SHA256 checksums:
- When caching, the proxy calculates and stores a SHA256 hash
- Before serving from cache, the hash is verified
- If verification fails, the cache is invalidated and the package is refetched
This prevents:
- Cache corruption from disk errors
- Manual tampering with cached files
- Serving compromised packages
Cache Poisoning Prevention
The proxy checks packages for malicious content before caching:
- Malicious packages are never cached
- If a package becomes flagged after being cached, it’s automatically removed
- Each request is checked against the latest database
Monitoring
Prometheus Metrics
The proxy exposes metrics for monitoring:
# Total number of malicious packages blocked
devguard_malicious_package_blocked_total{ecosystem="npm",package="fake-malicious-package"} 5
# Example queries
# Blocked packages by ecosystem
sum by (ecosystem) (devguard_malicious_package_blocked_total)
# Top 10 blocked packages
topk(10, devguard_malicious_package_blocked_total)Testing
DevGuard includes test packages for verifying the proxy functionality:
fake-malicious-npm-package(npm)github.com/fake-org/malicious-package(Go)fake-malicious-pypi-package(PyPI)
These test packages are safe to use and will always be blocked by the proxy.
Example Test
Create a test project with a malicious package:
package.json (npm):
{
"dependencies": {
"lodash": "^4.17.21",
"fake-malicious-npm-package": "1.0.0"
}
}Run npm install:
- âś…
lodashwill install successfully - ❌
fake-malicious-npm-packagewill be blocked
Check the DevGuard logs and Prometheus metrics to see the blocked attempt.
API Reference
Proxy Endpoints
GET /api/v1/dependency-proxy/npm/*- NPM proxyGET /api/v1/dependency-proxy/go/*- Go modules proxyGET /api/v1/dependency-proxy/pypi/*- PyPI proxy
Response Headers
X-Cache: HIT|MISS- Indicates if the response was served from cacheX-Proxy-Type: npm|go|pypi- Identifies the proxy typeX-Malicious-Package: blocked- Present when a package is blocked
Status Codes
200 OK- Package successfully proxied403 Forbidden- Malicious package blocked503 Service Unavailable- Database not yet loaded502 Bad Gateway- Upstream registry error