Constrain followed source symlinks to the project root during tar staging
Maintainers usually reply within 2 days
@jonasz-lasut is already working on this.
Since Sep 18, 2026.
Assessment
This issue has not been assessed yet.
Description
Summary
internal/filesystem.FSToTar follows symlinks with filepath.EvalSymlinks and walks the resolved target without enforcing a project-root boundary. Builders that use filesystem.WithSymlinkBasePath can therefore stage readable files outside the project.
Required changes
Add a project-root boundary for followed symlinks during filesystem tar staging. Preserve valid symlinks that resolve within the project, including documented sibling-crate sharing. Reject or exclude symlinks that resolve outside the project root.
Pass the real project-root path through the relevant build and tar-staging APIs. Do not use the function directory as the boundary because functions can intentionally link to sibling project directories.
Rationale
The Rust builder newly uses the shared staging behavior. KCL and Go-templating builders already use it, and their staged files can be included in published image layers. This issue requires a shared fix rather than a Rust-specific restriction.
Affected areas
internal/filesystemtar and symlink handling- Build-context plumbing that can provide the real project-root path
- Function builders that use
filesystem.FSToTarwithfilesystem.WithSymlinkBasePath
Acceptance criteria
- A followed symlink cannot cause files outside the project root to be added to a tar archive.
- Symlinks to locations inside the project root remain supported.
- A function can continue to share a crate from a sibling directory through an in-project symlink.
- Tests cover direct and nested external symlinks, in-project symlinks, and the sibling-crate workflow.
- The behavior applies consistently to Rust, KCL, and Go-templating staging paths.
Backlinks
- Pull request: https://github.com/crossplane/cli/pull/374
- Review comment: https://github.com/crossplane/cli/pull/374#discussion_r4046945303
- Requested by: @jonasz-lasut
- Dominant language
- Go
- Stars
- 19
- Forks
- 33
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 40
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from crossplane/cli
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
crossplane/cli#282 ·
Maintainers usually reply within 2 days
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 48/100
crossplane/cli#401 ·
Maintainers usually reply within 2 days
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 68/100
crossplane/cli#400 ·
Maintainers usually reply within 2 days
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 70/100
crossplane/cli#399 ·
Maintainers usually reply within 2 days
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
crossplane/cli#398 ·
Maintainers usually reply within 2 days
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
linonetwo/cpa-session-archive#25 ·
Maintainers usually reply within 1 day
-
area/testing kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
agent-butler-finding bug
Difficulty 1/5 Under an hour Newbie friendliness 94/100
jordansmall/spindrift#4367 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 Under an hour Newbie friendliness 90/100
Maintainers usually reply within 1 day