Skip to content

[Sad Catapella B4][Discovery] Symbolic links can silently import images outside the experiment root #81

Closed

Description

@guijacquemet

Baseline and classification

Sad Catapella Batch 4; main at d7a538e56d41ac1093ba79adcad397c21b3dfd32. Confirmed control-flow/path-policy gap by source inspection; no filesystem reproducer or tests executed. Exact desired symlink policy requires an explicit decision.

Source evidence

  • _Walker.visit() lines 615–656 calls entry.is_dir() (follows directory symbolic links by default), appends TIFF entries regardless of whether their resolved target lies under the experiment root, and recursively enters directories without resolving targets or checking inode/realpath membership.
  • _Walker.relative() validates lexical relative paths only. discover_experiment() resolves the root but not the individual entries.
  • run_experiment() later derives paths from these discovered entries and file_entry_for() fingerprints the followed data. The consumer can therefore process a dataset the selected experiment tree does not physically own.

Deterministic fixture to add

  1. Create experiment/ctrl/rep1/linked as a symlink to a directory outside the experiment containing image.tif (or symlink a TIFF inside a leaf to an external TIFF). Discovery currently has no check against the outside target; if the link remains within the maximum folder depth, those pixels can be read and assigned in-experiment labels.
  2. Create link to another dataset subtree (duplicate physical image under two logical identities). Check whether it is silently pooled as independent observations.
  3. Include broken links, symlinked OME-Zarr stores, link to the experiment root at an allowed depth, and entry.is_dir() access errors. Note: the current three-level depth guard limits recursion; do not claim infinite recursion without demonstration.

Impact and fix

Unintended external data inclusion or double-counting under distinct biological labels; surprising behavior when an experiment is moved or shared. Decide whether to (A) reject every symlink with an actionable linked_input error or (B) allow explicitly configured links only after canonical containment/cycle/duplicate-target validation and provenance recording. Never silently traverse out of the selected root. Tests should assert no pixel reads on refusal.

Performance: use a bounded canonical-path/inode set per scanned entry if link support is chosen; Numba is inappropriate.

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