Skip to content

feat(images): harden OCI image pull security#429

Open
DorianZheng wants to merge 2 commits intomainfrom
feat/oci-image-pull-security-hardening
Open

feat(images): harden OCI image pull security#429
DorianZheng wants to merge 2 commits intomainfrom
feat/oci-image-pull-security-hardening

Conversation

@DorianZheng
Copy link
Copy Markdown
Member

Summary

Hardens the OCI image pull pipeline by closing security gaps identified by comparing with Docker (containerd) and Podman (containers/image):

  • Size validation: LayerInfo now carries expected size from manifest descriptors; StagedDownload::commit() rejects blobs with mismatched size (prevents disk exhaustion from oversized blobs)
  • Foreign layer URL rejection: layers_from_image() rejects layers with non-distributable media types or foreign URLs (CVE-2020-15157 credential leak mitigation)
  • HashingWriter: New AsyncWrite wrapper computes SHA256 inline during download, eliminating the post-download file re-read and halving I/O while maintaining independent verification from oci-client
  • DiffID verification: verify_diff_id() decompresses and hashes layer tarballs to verify uncompressed content matches rootfs.diff_ids from the image config

Also marks mount_security_integration as #[ignore] — it's a research/feasibility test that installs gcc inside a VM and consistently times out in pre-push hooks.

Test plan

  • 625 unit/lib tests pass (cargo test -p boxlite --lib)
  • Clippy clean (cargo clippy -p boxlite --tests -- -D warnings)
  • 12 new tests covering: size validation (correct/wrong/zero/negative), foreign URL rejection (nondistributable media type, foreign URLs, Docker foreign type, empty URLs, normal layers), HashingWriter correctness, DiffID verification (correct hash, wrong hash, uncompressed tarball)
  • CI integration tests pass

…ID verification

Add four security improvements to the OCI image pull pipeline, closing
gaps identified by comparing with Docker (containerd) and Podman
(containers/image):

- Size validation: LayerInfo now carries expected size from manifest
  descriptors; StagedDownload.commit() rejects blobs with mismatched
  size before hash check (prevents disk exhaustion from oversized blobs)
- Foreign layer URL rejection: layers_from_image() rejects layers with
  non-distributable media types or foreign URLs (CVE-2020-15157
  mitigation)
- HashingWriter: new AsyncWrite wrapper computes SHA256 inline during
  download, eliminating the post-download re-read and halving I/O while
  maintaining independent verification from oci-client
- DiffID verification: verify_diff_id() decompresses and hashes layer
  tarballs to verify uncompressed content matches rootfs.diff_ids from
  the image config, called during layer_extracted()
The mount_security_integration test installs gcc + musl-dev +
linux-headers inside a VM and compiles a C program to probe ID-mapped
mount feasibility. This takes >10 minutes and consistently times out
in the pre-push hook's 600s limit.

This is a research/feasibility probe, not a regression guard — mark it
#[ignore] so it only runs when explicitly requested:
  cargo test -p boxlite --test mount_security -- --ignored --nocapture
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant