Dev.to Security 🔐 Cybersecurity 👁 0 📖 3 min read

Keep Local Git Transports Out of Recursive Submodule Fetches

Keep Local Git Transports Out of Recursive Submodule Fetches A repository's .gitmodules file can point a submodule at a remote URL, a local path, or a helper transport. When a build or review process initializes submod

Keep Local Git Transports Out of Recursive Submodule Fetches

A repository's .gitmodules file can point a submodule at a remote URL, a local path, or a helper transport. When a build or review process initializes submodules recursively, those URLs can affect what Git fetches and where it reads from. The protocol.file.allow setting is one of the controls that determines whether a local transport is available without user interaction.

The policy tiers are not interchangeable

Git's configuration documentation describes protocol policies such as always, never, and user. A user-initiated clone can use a policy marked user, while a command that executes clone or fetch with no user input, such as recursive submodule initialization, may require a different policy. Known-safe network protocols have defaults that differ from local and external helpers.

CI systems often fetch repositories automatically. A developer may reasonably allow a local file URL in an interactive workflow. That does not prove the same URL should be available to a recursive submodule initializer. Set the policy for the automation environment instead of inheriting a developer's global configuration.

Local paths can change the data source

A file transport can read from a local repository or path. If a checked-out .gitmodules file points to an unexpected path, the build may pull content from the machine rather than from the intended remote origin. The result can be a confusing provenance gap: the top-level repository has a reviewed commit, while a submodule's content came from another source.

The danger is not limited to malicious URLs. A leftover absolute path from a developer's workstation can make a build depend on a directory that happens to exist on the runner. A symlink or mount can change what that path resolves to. Review the resolved URL and the submodule commit, not just the displayed project name.

Make recursion visible

Before a recursive clone, inspect .gitmodules and record the name, path, URL, and branch fields. Check that URLs use an approved transport. If a submodule is shared with a repository that has different transport needs, document the exception rather than granting file access globally.

Use a clean build agent with no private repositories mounted at predictable paths. Run the checkout with the intended protocol policy and inspect the resolved submodule commit. Then run a negative test in which a local path is not authorized. Confirm that the command fails before the build consumes the content.

Do not store credentials in a URL inside .gitmodules. Use the CI provider's credential mechanism and a remote transport that the runner is designed to authenticate. Mask tokens in logs and avoid printing full command lines that contain secrets.

Review the update path too

Submodule update behavior can inherit values from .gitmodules, but Git does not copy a custom update command for security reasons. That protection is not a reason to ignore the file. A branch setting or URL change can alter which commit is fetched later.

After checkout, compare the submodule commit to the expected lock or manifest. Generate software provenance from the resolved content, not only from the parent repository. If the build system supports a dependency inventory, include the submodule identity and source URL.

Keep a small policy test in CI. A clean runner should fetch the approved remote, reject an unexpected local transport, and produce the expected commit hash. This makes the transport decision part of the build and removes reliance on a global Git configuration that a different operator may have changed.

References

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.