Skip to content

Security: Bundle loader allows symlink escape leading to out-of-root file reads #125

@abdussatter401

Description

@abdussatter401

Summary

The FastRender bundle loader follows filesystem symlinks when resolving files referenced in bundle.json and does not enforce canonical bundle-root containment. As a result, a crafted bundle can reference files outside the bundle directory via a symlink, leading to unintended local file disclosure.

Vulnerability Class

  • CWE-59: Improper Link Resolution Before File Access
  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory

Affected Component

src/resource/bundle.rs

Relevant code path:

  • fastrender::resource::bundle::Bundle::load
  • load_directory
  • manifest-driven file resolution

Root Cause

The bundle loader validates that manifest paths are relative and do not contain .., but it does not prevent symlink traversal.

The loader performs roughly the following logic:

target = base_path.join(relative_path)
File::open(target)

If the joined path is a symlink that points outside the bundle root, the filesystem resolves the link and allows the external file to be opened.

There is no canonicalization check ensuring that the resolved path remains within the bundle directory.

Impact

If an attacker can supply a crafted directory bundle, they may cause FastRender to read arbitrary files outside the bundle root that are accessible to the process.

Example exposures could include:

  • local configuration files
  • API tokens stored in readable files
  • user data files

This results in local file disclosure within the process security context.

Proof of Concept

A proof-of-concept demonstrating the issue is available here:

https://github.com/abdussatter401/fastrender-cve-bundle-symlink-escape

The PoC:

  1. Creates a bundle directory
  2. Creates a file outside the bundle root
  3. Creates a symlink inside the bundle pointing to that external file
  4. References the symlink in bundle.json
  5. Calls Bundle::load(...)
  6. Confirms the external file contents are returned

Suggested Remediation

Before opening manifest-referenced files, enforce canonical path containment.

Example mitigation approach:

  1. Canonicalize the bundle root directory.
  2. Join the manifest path with the bundle root.
  3. Canonicalize the resulting path.
  4. Reject the path if it does not start with the canonical bundle root.

Optional hardening:

  • Reject symlinks outright
  • Use O_NOFOLLOW semantics where supported.

Disclosure Note

This issue is being reported as part of responsible security research.
A CVE request will also be submitted.

Please let me know if additional information or reproduction details are helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions