Full Report
There are two types of "next line" characters in use: carriage return and newline. On original typewriters, carriage return moved the cursor to the left of the margin while the newline (line feed) went down a single line. This made the characters distinct in many ways. Unix tried to just use a newline (\n) while Windows required a CRLF still. .gitmodules is a configuration file in a Git repo that controls submodules. When parsing, it attempts to support both cases described above - Unix \n and \r\n. It should be noted that besides reading these files, git can also write to them directly. When writing a configuration file, git will "quote" the value if it contains a double quote, space, semicolon, or hashtag. Upon writing this information to another file, a final carriage return would effectively be skipped. The actual vulnerability is really a parser difference between the reading and the writing. In other words, it creates a potential time-of-check versus time-of-use security issue. Here's the path: Create a submodule file that contains the path "foo^M" where ^M is the line feed. The file location is validated at this point. When this is written to .git/modules/foo/config the content is written as foo^M without the quotes. When the configuration file is read later, it will parse this as foo without the ^M. This is because the parser will strip out the final CR at the end of a line. Practically, this means that writing to a file path now has a different meaning than intended. This could lead to symbolic links going to unintended locations on the file system, escaping the cloned directory's sandbox. The PoC writes to .git/hooks to force it to write arbitrary code and open upon finishing the clone. Pretty neat! The analysis at the end is pretty interesting. Carriage returns led to another bug in the credential helper protocol of git that led to credential leakage. Another one around configuration parsing was found in 2023. These differences in components of git are similar to CRLF injection in HTTP. Overall, a good post that demonstrates a severe vulnerability in Git. I appreciate the clear permission boundaries of git and would like to see more research into it.
Analysis Summary
# Vulnerability: Git Carriage Return Configuration Injection
## CVE Details
- **CVE ID**: CVE-2025-48384
- **CVSS Score**: Not explicitly stated in text (High/Critical potential due to RCE)
- **CWE**: CWE-93 (Improper Neutralization of CRLF Sequences / 'CRLF Injection') / CWE-436 (Interpretation Conflict)
## Affected Systems
- **Products**: Git, GitHub Desktop, and other software embedding Git.
- **Versions**: Versions prior to the July 2025 security release.
- **Configurations**: Unix-like platforms are primarily at risk. The vulnerability is triggered during a `git clone --recursive` operation on an untrusted repository containing malicious submodules.
## Vulnerability Description
The vulnerability arises from a discrepancy between how Git's configuration parser **reads** values versus how it **writes** them, specifically regarding Carriage Return (CR/`\r`) characters.
1. **Reading**: The parser strips a trailing `\r` from a line to support DOS-style line endings (`\r\n`).
2. **Writing**: When Git writes a configuration value (like a submodule path) to a file, it only uses double quotes if the value contains spaces, semicolons, or hashtags. It does *not* automatically quote values containing only a trailing CR.
3. **The Conflict**: An attacker can create a `.gitmodules` file with a submodule path ending in a CR (e.g., `"foo\r"`). While initially validated, when Git writes this path to the internal `.git/modules/foo/config` file, it writes the CR unquoted.
4. **Injection**: Upon the next read, the parser strips the "meaningless" trailing CR. This interpretation difference allows an attacker to manipulate file paths, leading to path traversal or the creation of unintended symbolic links.
## Exploitation
- **Status**: PoC available (conceptually described as a modification of CVE-2024-32002; test cases exist in the fix commit).
- **Complexity**: Low to Medium (requires crafting a malicious `.gitmodules` file).
- **Attack Vector**: Network (Remote repository cloned by a local user).
## Impact
- **Confidentiality**: High (Potential to leak files or credentials).
- **Integrity**: High (Arbitrary code execution via writing to `.git/hooks`).
- **Availability**: High (Ability to corrupt the repository or local filesystem).
## Remediation
### Patches
- Users should update to the Git security releases announced on **July 9, 2025**.
- Relevant fix commit: `05e9cd64ee23bbadcea6bcffd6660ed02b8eab89`
### Workarounds
- Avoid using `git clone --recursive` on untrusted repositories until the client is updated.
- Disable automatic submodule recursion.
## Detection
- **Indicators of Compromise**: Presence of `.gitmodules` files containing paths with literal carriage return characters (`^M` or `\r`).
- **Detection Methods**: Inspecting the `.git/modules/` directory for unexpected hook scripts or configuration files that appear to have been "smuggled" via submodule path manipulation.
## References
- **Vendor Advisory**: [github\[.\]blog/open-source/git/git-security-vulnerabilities-announced-6/](https://github.blog/open-source/git/git-security-vulnerabilities-announced-6/)
- **Technical Analysis**: [dgl\[.\]cx/2025/07/git-clone-submodule-cve-2025-48384](https://dgl.cx/2025/07/git-clone-submodule-cve-2025-48384)
- **Git Source**: [github\[.\]com/git/git/commit/05e9cd64ee23bbadcea6bcffd6660ed02b8eab89](https://github.com/git/git/commit/05e9cd64ee23bbadcea6bcffd6660ed02b8eab89)