Skip to content

component manifest paths can escape the toolchain install prefix #4943

Open

Description

@cachebag

manifest.in component paths appear to be trusted after decoding. ComponentPart::decode() converts the path string directly into a PathBuf, and transaction operations only guard with relpath.is_relative(). However, paths containing parent components like ../outside are still relative.

Those paths are later joined with the install prefix via InstallPrefix::abs_path(), so a component manifest entry such as:

file:../outside-file

can target a path outside the toolchain directory during install. Those paths are persisted into component manifests and can later be used during uninstall; rollback also uses the recorded transaction paths.

path: PathBuf::from(path_str.as_ref()),

assert!(relpath.is_relative());
let abs_path = ChangedItem::dest_abs_path(&self.prefix, component, &relpath)?;
utils::rename("component", src, &abs_path, self.permit_copy_rename)?;

Ideally, component manifest paths should be confined to the toolchain install prefix. Absolute paths, prefix paths, empty paths, and paths containing .. should be rejected as corrupt component manifests.

It may also be worth validating that the package source path stays under the extracted package root.

Ref:

Activity

  1. djc commented on Jul 7, 2026

    @djc
    Contributor

    Not saying we shouldn't fix it, but pretty sure the rustup user is trusting the source of the manifest anyway, right? They could probably do worse things than install stuff outside of the prefix.

  2. cachebag commented on Jul 7, 2026

    @cachebag
    ContributorAuthor

    @djc yes, it is totally not high severity or critical. more of a cheap in-depth defense. however, the implication of this i presume is also that malformed component paths can make rustup itself write, remove, or roll back files outside the toolchain prefix before any installed binary is even run.

  3. rami3l commented on Jul 7, 2026

    @rami3l
    Member

    @cachebag Thanks for this issue.

    AFAIK rustup is pretty much executing near-arbitrary manifest here and I'm not sure if there is an attack vector associated to it.

  4. cachebag commented on Jul 7, 2026

    @cachebag
    ContributorAuthor

    @rami3l
    as aforementioned, rustup seems to intend component paths to stay within the toolchain prefix, but .. paths let rustup’s own install/uninstall/rollback operations escape that prefix, so this seems worth treating as a containment hardening/correctness?

    i agree that the severity from a threat-model standpoint is probably low since the manifest is trusted. but it still seems incorrect nonetheless.

  5. rami3l commented on Jul 9, 2026

    @rami3l
    Member

    @cachebag There is no need to close this though... I guess somewhere down the road this might turn out to be relevant, it's just that I don't think we should do something about it right now 🙏

  6. reopened this on Jul 9, 2026
  7. Functionhx commented on Jul 11, 2026

    @Functionhx

    I can take this. I'll add path traversal hardening for component manifest paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions