Security and limits
Network trust
The owned default transport permits HTTPS only, disables automatic redirects, cookies, and proxies, and validates DNS results. Its connection callback connects directly to validated addresses while TLS validates the repository hostname. Private/local/metadata addresses and non-global IPv6 are rejected. URL userinfo, queries, and fragments are rejected; the library itself adds the Git discovery query.
AllowPrivateHosts = true bypasses address restrictions for explicitly trusted internal hosts. It does not enable HTTP or redirects. Never enable it broadly for arbitrary user-supplied repository URLs.
An injected HttpClient is caller-owned and trusted. Configure its handler with AllowAutoRedirect = false, trusted headers/cookies, and equivalent proxy and connection-time DNS policy. The library performs DNS preflight and rejects changed response URLs it observes, but cannot inspect or override the handler or undo requests it already redirected. Prefer the default owned transport for built-in SSRF defenses.
Retries, secrets, and deadlines
Only transient HTTP statuses 429, 502, 503, and 504 are retried, with bounded exponential delays. MaxRetries counts retries after the initial attempt. The client does not retry response-stream consumption, pack processing, file callbacks, or access failures. Handler side effects are never replayed.
RequestTimeout covers each transport send operation, its retry loop, and response consumption. It is not an overall snapshot deadline. Cancellation propagates, and per-operation temporary stores are disposed on exit. Do not log authorization headers or secrets in application credential providers. HTTP access errors have sanitized messages; remote bodies/progress/error text are not logged.
Resource defaults
GitClientOptions.cs is the authoritative source. Budgets span all requests and packs in one public operation and reset for the next operation.
| Option | Default | Meaning |
|---|---|---|
MaxTransferBytes |
2 GiB | HTTP response bytes including framing |
MaxBlobBytes |
512 MiB | One reconstructed blob |
MaxDecompressedBytes |
4 GiB | Total inflated and reconstructed bytes |
MaxTemporaryDiskBytes |
8 GiB | Cumulative temporary writes, including packs, duplicates, and delta intermediates |
MaxMemoryBytes |
64 MiB | Accounted metadata and fixed-buffer budget |
MaxObjectCount |
100,000 | Objects across packs |
MaxTreeDepth |
128 | Directory nesting |
MaxPathLength |
4,096 | Repository path characters |
MaxDeltaDepth |
64 | Delta chain depth |
BlobBatchSize |
128 | Wanted blob IDs per selective request |
RequestTimeout |
5 minutes | Request deadline including consumption and retries |
MaxRetries |
2 | Transient status retries |
AllowPrivateHosts |
false |
Explicit trust for private network destinations |
SkipUnsupportedEntries |
false |
Skip unsupported content and report warnings |
TemporaryDirectory |
null |
Use system temporary storage as the parent |
Numeric budgets must be positive; memory must be at least 1 MiB. Tree depth is restricted to 1–512, path length to 1–1,000,000, batch size to 1–4,096, and retries to 0–10.
Memory accounting excludes .NET runtime, HTTP handler, caller, and callback allocations. Metadata uses conservative per-object/per-path allowances; a large tree can exhaust the budget despite a small compressed pack. Temporary disk accounting is cumulative rather than peak live disk usage. Set TemporaryDirectory to a trusted volume with appropriate permissions and sufficient space. Pack data, inflated objects, and reconstructed deltas use per-operation temporary files rather than retaining full file contents in managed memory.
Input and disk validation
Pack processing checks PACK v2/v3 framing, SHA-1 object IDs and pack checksum, object sizes, zlib boundaries, OFS_DELTA and REF_DELTA chains (including forward references), missing bases, and malformed delta instructions. Trees are validated for malformed entries, unsupported modes, paths, and missing objects. SHA-256 repositories are rejected. Selective responses containing unrelated blobs and tree-only responses containing blobs are rejected; rejection cannot undo bytes already transmitted by a nonconforming server.
DiskFileHandler rejects traversal, rooted paths, backslashes, NUL, invalid/reserved Windows names, case collisions, and symlink/reparse-point ancestors. It cleans sibling temporary outputs when a write fails or is canceled. Managed path checks cannot eliminate races if another process swaps directories for links during a write. The destination must be exclusively controlled by a trusted process. Earlier successfully delivered files remain after later failure.
Unsupported content and providers
Symlinks and submodules appear in listings. Full snapshots reject them by default; filtered snapshots select regular/executable files only. Standard Git LFS pointer signatures cause failure rather than delivering incomplete LFS content. With SkipUnsupportedEntries = true, unsupported full-snapshot entries and selected LFS pointers produce warnings and an incomplete result.
There is no SSH, plain HTTP, LFS download, submodule recursion, history, write/push operation, hook/script execution, or checkout filter execution. No automatic full snapshot fallback follows selective OID refusal. GitHub, GitLab, and Azure DevOps endpoints are usable only when their protocol capabilities and OID policies permit the requested operation. The root README records prior live GitHub testing; authenticated/provider-specific coverage requires opt-in tests against authorized repositories.