Skip to content

fix: prevent writable HEAD markers from hiding submodule Git metadata #285

Description

@danny-avila

Problem

The collectSubmoduleGitDirs helper added in #276 identifies a Git directory by a regular file named HEAD. Once it finds that file, it only descends into a child named modules and skips the remaining directory children. HEAD remains writable by root sandbox commands.

This allows an intermediate directory in a slash-containing submodule path to hide an existing submodule from the next command's deny scan:

  1. Create a real submodule whose Git directory is .git/modules/group/project.
  2. In one sandbox command, plant a regular file at .git/modules/group/HEAD.
  3. On the next command, the scan treats .git/modules/group as the Git directory and never visits its project child.
  4. The real submodule's config and hooks are omitted from explicit write denies and can then be modified. Those settings can affect a subsequent trusted Git invocation.

Removing an existing submodule's HEAD can also make its own config and hooks disappear from the collected set until the file is restored. The scan is recomputed per command, so writable discovery markers must not narrow traversal.

Suggested follow-up

Walk descendant directories even after discovering a HEAD, or otherwise ensure a writable marker cannot cause an existing protected Git directory to be skipped. Preserve support for nested submodules and slash-containing names.

Add regressions covering a planted intermediate HEAD, a removed real HEAD, and the resulting config/hooks denies across consecutive commands.

Bugbot reported this during the upstream import into ClickHouse/ai: https://github.com/ClickHouse/ai/pull/4153#discussion_r4160697007

Affected code: packages/code/src/native-sandbox.ts, collectSubmoduleGitDirs.

Activity

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