Files
git.stella-ops.org/docs/modules/scanner/bun-analyzer-gotchas.md
StellaOps Bot dd0067ea0b
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Refactor code structure for improved readability and maintainability
2025-12-06 21:48:12 +02:00

5.5 KiB

Bun Analyzer Developer Gotchas

This document covers common pitfalls and considerations when working with the Bun analyzer.

Bun's isolated linker (bun install --linker isolated) creates a flat store under node_modules/.bun/ with symlinks for package resolution. This differs from the default hoisted layout.

Implications:

  • The analyzer must traverse node_modules/.bun/**/package.json in addition to node_modules/**/package.json
  • Symlink safety guards are critical to prevent infinite loops and out-of-root traversal
  • Both logical and real paths are recorded in evidence for traceability
  • Performance guards (MaxSymlinkDepth=10, MaxFilesPerRoot=50000) are enforced

Testing:

  • Use the IsolatedLinkerInstallIsParsedAsync test fixture to verify .bun/ traversal
  • Use the SymlinkSafetyIsEnforcedAsync test fixture for symlink corner cases

2. node_modules/.bun/ Scanning Requirement

Unlike Node.js, Bun may store packages entirely under node_modules/.bun/ with only symlinks in the top-level node_modules/. If your scanner configuration excludes .bun/ directories, you will miss dependencies.

Checklist:

  • Ensure glob patterns include .bun/ subdirectories
  • Do not filter out hidden directories in container scans
  • Verify evidence shows packages from both node_modules/ and node_modules/.bun/

3. bun.lockb Migration Path

The binary lockfile (bun.lockb) format is undocumented and unstable. The analyzer treats it as unsupported and emits a remediation finding.

Migration command:

bun install --save-text-lockfile

This generates bun.lock (JSONC text format) which the analyzer can parse.

WebService response: When only bun.lockb is present:

  • The scan completes but reports unsupported status
  • Remediation guidance is included in findings
  • No package inventory is generated

4. JSONC Lockfile Format

bun.lock uses JSONC (JSON with Comments) format supporting:

  • Single-line comments (// ...)
  • Multi-line comments (/* ... */)
  • Trailing commas in arrays and objects

Parser considerations:

  • The BunLockParser tolerates these JSONC features
  • Standard JSON parsers will fail on bun.lock files
  • Format may evolve with Bun releases; parser is intentionally tolerant

5. Multi-Stage Build Implications

In multi-stage Docker builds, the final image may contain only production artifacts without the lockfile or node_modules/.bun/ directory.

Scanning strategies:

  1. Image scanning (recommended for production): Scans the final image filesystem. Set include_dev: false to filter dev dependencies
  2. Repository scanning: Scans bun.lock from source. Includes all dependencies by default (include_dev: true)

Best practice: Scan both the repository (for complete visibility) and production images (for runtime accuracy).

6. npm Ecosystem Reuse

Bun packages are npm packages. The analyzer:

  • Emits pkg:npm/<name>@<version> PURLs (same as Node analyzer)
  • Uses ecosystem = npm for vulnerability lookups
  • Adds package_manager = bun metadata for differentiation

This means:

  • Vulnerability intelligence is shared with Node analyzer
  • VEX statements for npm packages apply to Bun
  • No separate Bun-specific advisory database is needed

7. Source Detection in Lockfile

bun.lock entries include source information that determines package type:

Source Pattern Type Example
No source / default registry registry lodash@4.17.21
git+https://... or git://... git VCS dependency
file: or link: tarball Local package
workspace: workspace Monorepo member

The analyzer records source type in evidence for provenance tracking.

8. Workspace/Monorepo Handling

Bun workspaces use a single bun.lock at the root with multiple package.json files in subdirectories.

Analyzer behavior:

  • Discovers the root by presence of bun.lock + package.json
  • Traverses all node_modules/ directories under the root
  • Deduplicates packages by (name, version) while accumulating occurrence paths
  • Records workspace member paths in metadata

Testing: Use the WorkspacesAreParsedAsync test fixture.

9. Dev/Prod Dependency Filtering

The include_dev configuration option controls whether dev dependencies are included:

Context Default include_dev Rationale
Repository scan (lockfile-only) true Full visibility for developers
Image scan (installed packages) true Packages are present regardless of intent

Override: Set include_dev: false in scan configuration to exclude dev dependencies from results.

10. Evidence Model

Each Bun package includes evidence with:

  • source: Where the package was found (node_modules, bun.lock, node_modules/.bun)
  • locator: File path to the evidence
  • resolved: The resolved URL from lockfile (if available)
  • integrity: SHA hash from lockfile (if available)
  • sha256: File hash for installed packages

Evidence enables:

  • Tracing packages to their origin
  • Validating integrity
  • Explaining presence in SBOM

CLI Reference

Inspect local workspace

stellaops-cli bun inspect --root /path/to/project

Resolve packages from scan

stellaops-cli bun resolve --scan-id <id>
stellaops-cli bun resolve --digest sha256:<hash>
stellaops-cli bun resolve --ref myregistry.io/myapp:latest

Output formats

stellaops-cli bun inspect --format json > packages.json
stellaops-cli bun inspect --format table