Skip to content

Allow kodata symlinks within the repository root#1698

Open
imjasonh with Copilot wants to merge 7 commits into
mainfrom
copilot/featuremigrate-to-nextjs-13
Open

Allow kodata symlinks within the repository root#1698
imjasonh with Copilot wants to merge 7 commits into
mainfrom
copilot/featuremigrate-to-nextjs-13

Conversation

Copilot AI commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

The kodata symlink hardening was too narrow: it rejected symlinks to files that are part of the same repository but live outside the package’s kodata/ directory, which breaks common layouts like shared LICENSE and repo-level config. This change keeps the exfiltration guard, but moves the trust boundary to the repository root when that boundary is knowable.

  • Problem

    • kodata/ symlinks were only allowed to resolve within kodata/ itself.
    • That blocked legitimate in-repo targets while correctly blocking host-file exfiltration.
  • Boundary resolution

    • Resolve the allowed root from the package directory’s git top-level (git rev-parse --show-toplevel).
    • If the build is not in a git checkout, fall back to the existing kodata/ root behavior.
    • Add KO_DATA_PATH_ALLOWED_ROOT to override the boundary for non-git builds or custom monorepo layouts.
  • Symlink enforcement

    • Keep the existing EvalSymlinksAbs → prefix containment check.
    • Apply that check against the resolved allowed root instead of only kodata/.
    • Continue rejecting any symlink target outside the allowed root.
  • Refactor

    • Split package directory resolution from kodata path resolution so allowed-root discovery can start from the import path’s source directory.
  • Examples covered

    • Allowed: cmd/app/kodata/LICENSE -> ../LICENSE
    • Rejected: cmd/app/kodata/ssh-key -> ~/.ssh/id_rsa
repo/
├── LICENSE
└── cmd/app/
    └── kodata/
        └── LICENSE -> ../LICENSE   # allowed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR broadens kodata/ symlink hardening to allow in-repo symlink targets by moving the trust boundary from the package’s kodata/ directory to the repository root when it can be determined (via git rev-parse --show-toplevel), while preserving protection against symlinks that resolve outside the allowed boundary. It also adds an environment variable override for non-git builds or custom layouts.

Changes:

  • Refactors package directory discovery (packageDir) so allowed-root resolution can be derived from the package source location.
  • Introduces allowed-root resolution logic (resolveKODataAllowedRoot) with precedence: KO_DATA_PATH_ALLOWED_ROOT → git repo top-level → kodata/ root fallback.
  • Updates walkRecursive to enforce symlink containment against the resolved allowed root and adds/updates tests for both allowed in-repo symlinks and rejected escaping symlinks.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
pkg/build/gobuild.go Resolves an allowed symlink boundary (repo root / override) and applies containment checks against it during kodata/ tarring.
pkg/build/gobuild_test.go Updates symlink traversal tests and adds coverage for allowed-root resolution behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/build/gobuild.go
Comment thread pkg/build/gobuild_test.go
@imjasonh imjasonh marked this pull request as ready for review July 6, 2026 19:24
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.

3 participants