Appendix g
Appendix G: Ecosystem-Specific Security Guides¶
This appendix provides quick-reference security guides for major programming language ecosystems. Each section covers lockfile management, security scanning, signing and verification, registry features, and common vulnerabilities specific to that ecosystem.
JavaScript/npm Security Best Practices¶
The JavaScript ecosystem, centered on npm (Node Package Manager), is the largest package ecosystem with over 2 million packages. Its size and the tendency toward many small dependencies create unique supply chain challenges.
Lockfile and Pinning¶
npm uses package-lock.json to lock dependency versions. Always commit this file to version control.
# Generate or update lockfile
npm install
# Install from lockfile only (CI/CD)
npm ci
# Audit lockfile for known vulnerabilities
npm audit
# Update a specific package
npm update lodash
Best Practices:
- Use npm ci in CI/CD pipelines instead of npm install
- Set save-exact=true in .npmrc to pin exact versions by default
- Review lockfile changes in pull requests—large diffs may indicate supply chain attacks
Security Scanning Tools¶
| Tool | Purpose | Command/Integration |
|---|---|---|
| npm audit | Built-in vulnerability scanner | npm audit |
| npm audit fix | Auto-fix vulnerabilities | npm audit fix |
| Snyk | Comprehensive scanning | snyk test |
| Socket | Supply chain threat detection | GitHub App integration |
| npm-check-updates | Find outdated packages | ncu |
# Run npm audit with JSON output for CI
npm audit --json > audit-results.json
# Fix vulnerabilities automatically (use with caution)
npm audit fix
# Force fixes that may include breaking changes
npm audit fix --force
Signing and Verification¶
npm supports package provenance through Sigstore integration since 2023.
# Publish with provenance (requires npm 9.5.0+)
npm publish --provenance
# Check if a package has provenance
npm view <package> --json | jq '.dist.attestations'
Verification: Look for the "Provenance" badge on npmjs.com package pages, indicating the package was built from a verified source repository.
Registry Security Features¶
- Two-factor authentication: Enable on npmjs.com for all publishing accounts
- Granular access tokens: Create tokens with limited scope and expiration
- npm Organizations: Use teams and access controls for shared packages
- Automated security advisories: npm automatically creates advisories for reported vulnerabilities
# Create a read-only automation token
npm token create --read-only
# Create a token limited to specific packages
npm token create --cidr=192.168.1.0/24
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Prototype pollution | Manipulating __proto__ |
Use Object.create(null), validate input |
| ReDoS | Catastrophic regex backtracking | Audit regex patterns, use safe-regex |
| Path traversal | ../ in file operations |
Validate and sanitize paths |
| Command injection | Unsanitized shell commands | Use execFile instead of exec |
| Typosquatting | loadsh vs lodash |
Verify package names carefully |
Quick-Reference Checklist¶
-
package-lock.jsoncommitted to version control -
npm ciused in CI/CD pipelines -
npm auditruns in CI with failure threshold - Two-factor authentication enabled on npm account
- Publish tokens use minimal required scope
-
.npmrcconfigured withsave-exact=true - Provenance enabled for published packages
- Dependencies reviewed before updating lockfile
-
postinstallscripts audited in dependencies
Documentation: npm Security Best Practices
Python/PyPI Security Best Practices¶
Python's package ecosystem centers on PyPI (Python Package Index). The ecosystem has made significant security improvements including trusted publishing and mandatory 2FA for critical projects.
Lockfile and Pinning¶
Python has multiple dependency management approaches. Choose based on project needs.
pip with requirements.txt:
# Generate pinned requirements
pip freeze > requirements.txt
# Install with hash verification
pip install --require-hashes -r requirements.txt
# Generate requirements with hashes
pip-compile --generate-hashes requirements.in
Poetry:
# Install from lockfile
poetry install --no-root
# Update lockfile
poetry update
# Export to requirements.txt
poetry export -f requirements.txt --output requirements.txt
Pipenv:
uv (recommended for new projects):
# Initialize project
uv init
# Add dependencies
uv add requests
# Generate/update lockfile
uv lock
# Install from lockfile (reproducible)
uv sync
# Install with frozen lockfile (CI/CD)
uv sync --frozen
uv is an extremely fast Python package manager written in Rust (10-100x faster than pip) that provides security-first defaults: - Generates cross-platform lockfiles with SHA-256 hashes by default - Replaces pip, pip-tools, pipx, poetry, pyenv, and virtualenv with a single tool - Hermetic builds ensure reproducibility across environments - Active development by Astral, creators of the Ruff linter
Best Practices:
- Always use a lockfile mechanism (uv.lock, poetry.lock, Pipfile.lock, or pinned requirements.txt)
- Use hash verification for production deployments
- Pin transitive dependencies, not just direct dependencies
Security Scanning Tools¶
| Tool | Purpose | Command |
|---|---|---|
| pip-audit | Vulnerability scanning | pip-audit |
| Safety | Vulnerability database check | safety check |
| uv-secure | Vulnerability scanning for uv.lock | uv-secure |
| Bandit | Static analysis for Python | bandit -r src/ |
| Semgrep | Pattern-based scanning | semgrep --config=p/python |
| pyup.io | Dependency monitoring | SaaS integration |
# Scan installed packages for vulnerabilities
pip-audit
# Scan requirements file
pip-audit -r requirements.txt
# Run Bandit with baseline
bandit -r src/ -b bandit-baseline.json
Signing and Verification¶
PyPI supports Trusted Publishing via OpenID Connect, eliminating the need for API tokens.
# GitHub Actions: Trusted Publishing
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: pypa/gh-action-pypi-publish@release/v1
Sigstore signing is available for packages:
# Sign a distribution
python -m sigstore sign dist/*.whl
# Verify a signature
python -m sigstore verify dist/*.whl
Registry Security Features¶
- Trusted Publishing: Publish from GitHub Actions without API tokens
- Mandatory 2FA: Required for critical projects (top 1% by downloads)
- Organization accounts: Team-based access control
- API tokens: Scoped tokens for automation
- Project quarantine: New projects held briefly for malware scanning
# Configure trusted publishing on PyPI
# 1. Go to PyPI project settings
# 2. Add GitHub repository as trusted publisher
# 3. Remove API token from GitHub secrets
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Pickle deserialization | pickle.loads(untrusted) |
Never unpickle untrusted data |
| YAML deserialization | yaml.load() unsafe by default |
Use yaml.safe_load() |
| SQL injection | String formatting in queries | Use parameterized queries |
| Command injection | os.system() with user input |
Use subprocess with lists |
| Path traversal | open(user_path) |
Validate paths, use pathlib |
Quick-Reference Checklist¶
- Lockfile committed (
uv.lock,poetry.lock,Pipfile.lock, or pinned requirements) - Hash verification enabled for production installs
-
pip-audit, Safety, oruv-secureruns in CI pipeline - Bandit static analysis configured
- Two-factor authentication enabled on PyPI
- Trusted Publishing configured for releases
- Virtual environments used for isolation
-
setup.pyreviewed for code execution during install - Private package index configured if using internal packages
Documentation: PyPI Security
Java/Maven Security Best Practices¶
The Java ecosystem uses Maven Central as its primary repository. The ecosystem has mature security tooling but requires explicit configuration for dependency locking.
Lockfile and Pinning¶
Maven doesn't have a native lockfile. Use these approaches for reproducible builds:
Dependency Management BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Maven Enforcer Plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
<dependencyConvergence/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
Gradle Lockfiles:
# Generate lockfile
./gradlew dependencies --write-locks
# Verify against lockfile
./gradlew dependencies --update-locks
Security Scanning Tools¶
| Tool | Purpose | Integration |
|---|---|---|
| OWASP Dependency-Check | Vulnerability scanning | Maven/Gradle plugin |
| Snyk | Comprehensive scanning | CLI and plugins |
| SpotBugs + Find Security Bugs | Static analysis | Maven plugin |
| Checkmarx | Enterprise SAST | CI integration |
<!-- OWASP Dependency-Check Maven Plugin -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.0</version>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
</configuration>
</plugin>
# Run dependency check
mvn dependency-check:check
# Generate SBOM
mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom
Signing and Verification¶
Maven Central requires GPG signing for all published artifacts.
# Generate GPG key
gpg --gen-key
# Sign artifact
mvn gpg:sign
# Verify signatures
mvn org.simplify4u.plugins:pgpverify-maven-plugin:check
<!-- PGP Verification Plugin -->
<plugin>
<groupId>org.simplify4u.plugins</groupId>
<artifactId>pgpverify-maven-plugin</artifactId>
<version>1.17.0</version>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
Registry Security Features¶
- GPG signing mandatory: All artifacts on Maven Central must be signed
- Namespace validation: Group IDs verified against domain ownership
- Immutable releases: Published versions cannot be modified
- Sonatype scans: Automated malware scanning on upload
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Deserialization | ObjectInputStream attacks |
Avoid Java serialization, use allowlists |
| XML External Entity (XXE) | Processing untrusted XML | Disable external entities |
| Log injection | Log4Shell (CVE-2021-44228) | Update Log4j, disable JNDI |
| SQL injection | String concatenation | Use PreparedStatement |
| Expression Language injection | Spring EL, OGNL | Sanitize inputs |
Quick-Reference Checklist¶
- Dependency versions explicitly declared
- Maven Enforcer Plugin configured
- OWASP Dependency-Check in build pipeline
- GPG signing configured for releases
- PGP verification enabled for dependencies
- SpotBugs with security rules enabled
- Sonatype account has 2FA enabled
- SBOM generated with CycloneDX plugin
- Transitive dependencies reviewed with
mvn dependency:tree
Documentation: Maven Central Security
Go Modules Security Best Practices¶
Go has built-in module support with strong supply chain security features, including the module checksum database and module proxy.
Lockfile and Pinning¶
Go uses go.sum as its lockfile, containing cryptographic checksums of all dependencies.
# Initialize module
go mod init example.com/myproject
# Add dependencies and update go.sum
go mod tidy
# Verify checksums
go mod verify
# Download dependencies
go mod download
Best Practices:
- Always commit both go.mod and go.sum
- Run go mod verify in CI to detect tampering
- Use go mod tidy to remove unused dependencies
# Vendor dependencies for hermetic builds
go mod vendor
# Build using vendored dependencies
go build -mod=vendor
Security Scanning Tools¶
| Tool | Purpose | Command |
|---|---|---|
| govulncheck | Official vulnerability scanner | govulncheck ./... |
| gosec | Static analysis | gosec ./... |
| Staticcheck | Comprehensive linter | staticcheck ./... |
| Trivy | Container and filesystem scan | trivy fs . |
# Install and run govulncheck
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
# Run gosec
gosec -fmt=json -out=results.json ./...
Signing and Verification¶
Go modules use the checksum database (sum.golang.org) for verification.
# Environment variables for checksum verification
export GOSUMDB=sum.golang.org
export GOFLAGS="-mod=readonly"
# Verify module checksums
go mod verify
Private modules: Configure GOPRIVATE for internal modules:
Registry Security Features¶
- Checksum Database: Immutable log of module checksums
- Module Proxy: Caching proxy (proxy.golang.org) provides availability
- Module Mirror: Ensures modules remain available even if source disappears
- Transparency Log: Append-only log prevents tampering
# Configure module proxy
export GOPROXY=https://proxy.golang.org,direct
# For private modules
export GOPROXY=https://proxy.golang.org,https://private.proxy.mycompany.com,direct
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Command injection | exec.Command with user input |
Validate inputs, avoid shell |
| Path traversal | Unsanitized file paths | Use filepath.Clean, validate |
| Integer overflow | Unchecked arithmetic | Use math package checks |
| Race conditions | Concurrent map access | Use sync.Map or mutexes |
| Slice bounds | Index out of range | Validate indices |
Quick-Reference Checklist¶
-
go.modandgo.sumcommitted to version control -
go mod verifyruns in CI pipeline -
govulncheckruns in CI pipeline -
gosecstatic analysis configured -
GOSUMDBnot disabled (default is secure) -
GOPRIVATEconfigured for internal modules - Vendoring used for reproducible builds (optional)
- Module versions use semantic versioning
- Major version changes use
/v2,/v3paths
Documentation: Go Module Security
Rust/crates.io Security Best Practices¶
Rust's package ecosystem (crates.io) benefits from memory safety guarantees and strong security practices.
Lockfile and Pinning¶
Rust uses Cargo.lock for dependency locking.
# Generate/update lockfile
cargo build
# Update specific dependency
cargo update -p serde
# Install exact versions from lockfile
cargo install --locked
Best Practices:
- Always commit Cargo.lock for applications
- Libraries may omit Cargo.lock from version control
- Use --locked flag in CI to ensure lockfile is respected
# Cargo.toml - pin specific version
[dependencies]
serde = "=1.0.193" # Exact version
# Or use caret (default, allows patch updates)
serde = "1.0" # Equivalent to ^1.0
Security Scanning Tools¶
| Tool | Purpose | Command |
|---|---|---|
| cargo-audit | Vulnerability scanning | cargo audit |
| cargo-deny | License and vulnerability checks | cargo deny check |
| cargo-crev | Code review system | cargo crev verify |
| clippy | Linting including security | cargo clippy |
# Install and run cargo-audit
cargo install cargo-audit
cargo audit
# Install and configure cargo-deny
cargo install cargo-deny
cargo deny init
cargo deny check
cargo-deny configuration (deny.toml):
[advisories]
vulnerability = "deny"
unmaintained = "warn"
yanked = "deny"
[licenses]
unlicensed = "deny"
allow = ["MIT", "Apache-2.0", "BSD-3-Clause"]
[bans]
multiple-versions = "warn"
deny = [
{ name = "openssl" } # Prefer rustls
]
Signing and Verification¶
crates.io does not currently require signing, but provides other integrity measures:
# Verify checksums (automatic with cargo)
cargo fetch
# Use cargo-crev for community code reviews
cargo install cargo-crev
cargo crev id new
cargo crev verify
Registry Security Features¶
- Immutable crates: Published versions cannot be modified
- Yanking: Problematic versions can be yanked (not deleted)
- Mandatory 2FA: Required for publishing
- API tokens: Scoped tokens for automation
- Rate limiting: Prevents abuse
# Create scoped token
# Via crates.io web interface
# Publish with token
cargo publish --token $CRATES_IO_TOKEN
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Unsafe code | unsafe blocks with bugs |
Minimize unsafe, audit carefully |
| FFI issues | C interop vulnerabilities | Wrap unsafe FFI in safe APIs |
| Integer overflow | Debug vs release behavior | Use checked_* methods |
| Dependency confusion | Internal crate names | Use organizations/namespacing |
| Build scripts | Malicious build.rs |
Review build scripts |
Quick-Reference Checklist¶
-
Cargo.lockcommitted for applications -
cargo auditruns in CI pipeline -
cargo denyconfigured and runs in CI - Two-factor authentication enabled on crates.io
- API tokens use minimal required scope
-
#![forbid(unsafe_code)]where applicable - Clippy warnings addressed
- Build scripts audited for dependencies
-
--lockedflag used in CI builds
Documentation: crates.io Security
Container Security Best Practices¶
Container security spans multiple ecosystems and requires attention to base images, build processes, and runtime configuration.
Base Image Selection and Pinning¶
# Pin to specific digest (most secure)
FROM node:20.10.0-alpine@sha256:abc123...
# Pin to specific version (good)
FROM node:20.10.0-alpine
# Avoid (mutable tags)
FROM node:latest
FROM node:20
Distroless and minimal images:
# Google Distroless (no shell, minimal attack surface)
FROM gcr.io/distroless/nodejs20-debian12
# Chainguard Images (SLSA, signatures, SBOMs)
FROM cgr.dev/chainguard/node:latest
Security Scanning Tools¶
| Tool | Purpose | Command |
|---|---|---|
| Trivy | Vulnerability and misconfiguration | trivy image myimage:tag |
| Grype | Vulnerability scanning | grype myimage:tag |
| Syft | SBOM generation | syft myimage:tag |
| Docker Scout | Docker-integrated scanning | docker scout cves myimage:tag |
| Snyk Container | Container scanning | snyk container test myimage:tag |
# Scan image for vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:latest
# Generate SBOM for container
syft myapp:latest -o spdx-json > sbom.json
# Scan filesystem during build
trivy fs --scanners vuln,secret,misconfig .
Signing and Verification¶
Use Sigstore Cosign for container signing:
# Install cosign
brew install cosign
# Sign container image (keyless)
cosign sign myregistry/myimage:tag
# Verify signature
cosign verify myregistry/myimage:tag
# Sign with SBOM attestation
cosign attest --predicate sbom.json myregistry/myimage:tag
Policy enforcement with Kyverno or OPA Gatekeeper:
# Kyverno policy: require signed images
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "myregistry/*"
attestors:
- entries:
- keyless:
issuer: https://accounts.google.com
subject: build@mycompany.com
Registry Security Features¶
| Registry | Security Features |
|---|---|
| Docker Hub | Content trust, vulnerability scanning, access tokens |
| GitHub Container Registry | OIDC publishing, vulnerability alerts, visibility controls |
| Amazon ECR | Image scanning, lifecycle policies, IAM integration |
| Google Artifact Registry | Vulnerability scanning, Binary Authorization |
| Azure Container Registry | Content trust, Defender scanning, managed identities |
# Enable Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# Configure registry credentials securely
docker login --username $USER --password-stdin myregistry.com < token.txt
Common Vulnerabilities¶
| Vulnerability Type | Example | Mitigation |
|---|---|---|
| Vulnerable base images | Outdated OS packages | Use updated, minimal images |
| Secrets in images | Credentials in layers | Multi-stage builds, secrets management |
| Excessive privileges | Running as root | Use non-root user, drop capabilities |
| Mutable tags | latest tag changes |
Pin by digest |
| Exposed ports | Unnecessary services | Minimize exposed ports |
Dockerfile security best practices:
# Use non-root user
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Multi-stage build (don't include build tools in final image)
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/index.js"]
Quick-Reference Checklist¶
- Base images pinned by digest
- Minimal/distroless base images used where possible
- Multi-stage builds eliminate build dependencies
- Container runs as non-root user
- No secrets embedded in image layers
- Trivy or equivalent scans in CI pipeline
- Images signed with Cosign
- SBOM generated and attested
- Registry uses access controls and scanning
- Signature verification enforced at deployment
- Image pull policies prevent mutable tags in production
Documentation: Docker Security, Sigstore
Quick-Reference Security Checklists by Ecosystem¶
Use these condensed checklists for rapid security assessment across ecosystems.
| Security Control | npm | PyPI | Maven | Go | Rust | Containers |
|---|---|---|---|---|---|---|
| Lockfile committed | package-lock.json |
uv.lock / poetry.lock |
Enforcer plugin | go.sum |
Cargo.lock |
Digest pinning |
| CI install command | npm ci |
uv sync --frozen |
mvn verify |
go mod verify |
cargo build --locked |
docker pull @sha256: |
| Vulnerability scanner | npm audit |
pip-audit / uv-secure |
OWASP Dep-Check | govulncheck |
cargo audit |
Trivy/Grype |
| Static analysis | ESLint security | Bandit | SpotBugs | gosec | Clippy | Dockerfile lint |
| 2FA on registry | Required | Required (critical) | Required | N/A | Required | Registry-dependent |
| Signing available | Provenance | Sigstore | GPG (required) | Checksum DB | Not yet | Cosign |
| SBOM tool | Syft | Syft/CycloneDX | CycloneDX plugin | Syft | cargo-sbom | Syft |
Universal Security Principles:
- Pin dependencies: Use lockfiles and verify checksums
- Scan continuously: Run vulnerability scanners in every CI build
- Update regularly: Keep dependencies current, not just when vulnerabilities appear
- Verify integrity: Enable signature verification where available
- Minimize surface: Use minimal dependencies and base images
- Automate updates: Use Dependabot, Renovate, or equivalent
- Monitor advisories: Subscribe to security notifications for critical dependencies