Docker 18.09.4 validates Git references before fetching builds
A small change to Docker's Git build contexts separates reference names from command options. The patch adds both an argument delimiter and validation at the URL parser.
A Git reference supplied as part of a build URL must remain a reference when Docker passes it to Git. Docker 18.09.4 corrects the case where that value can instead become a command option. The release notes, dated March 28, identify reference validation as the builder correction. The implementation is short, but it addresses two different places where the same untrusted value can acquire meaning.
The underlying Moby pull request 38944 was opened on March 26 and merged on March 27. Its description credits a fix by Tonis Tiigi and thanks Etienne Stalmans for pointing out the issue. It explains why inserting an option delimiter into the fetch command is useful but does not exhaust the change. A checkout operation could also encounter the reference, so the patch adds validation before either operation can use it.
I like Docker's repeatable build description because it makes an environment an explicit artifact. Remote build contexts introduce another input to that description. Their URLs select source code, but the machinery interpreting those URLs must preserve the distinction between a source revision and instructions to the source-control program.
An argument array still needs an option boundary
The patch changes fetchArgs, the helper that constructs Git's fetch arguments. For a shallow fetch, its expected output previously placed the reference immediately after origin. The updated test expects a separator before the reference.
fetch --depth 1 origin -- master
This example is the ordinary master case from the patch's test expectations. The added -- establishes a boundary between Git options and the reference operand. The shallow-fetch decision is separate. A test for the non-shallow HTTP case receives the same delimiter without the depth option.
An argument array controls where one argument ends and another begins. It does not control whether the receiving program interprets a particular argument as an option. That second interpretation belongs to Git. The bug therefore illustrates a limit of reasoning only about shell quoting. Docker can assemble discrete arguments while still giving a reference value unintended authority over command behavior.
The helper's updated tests cover smart HTTP, the non-shallow HTTP case, and the Git transport case. Each expected array places -- before the reference. This is useful evidence of the intended contract because the protection does not depend on whether fetching that remote supports a shallow clone. The option boundary stays present across those command shapes.
The fix also avoids imposing a different spelling on an ordinary reference. In the illustrated case, master remains the final argument. The added element changes how Git interprets the position, while the requested revision remains the same. That is a narrow compatibility property, separate from rejecting values that should never have been accepted as references.
Validation protects later uses of the reference
The parser receives a second change. After processing the remote URL, parseRemoteURL rejects a reference beginning with a hyphen. Its error identifies an invalid refspec. This happens before the parsed repository description is returned to its caller.
That location matters because an accepted repository description can outlive one fetch invocation. A value that is safe in a fetch command with an explicit delimiter may still be unsafe in another command that uses different argument handling. The pull-request description specifically mentions checkout as the reason to keep custom validation as well as the cleaner fetch delimiter.
The two protections consequently answer different questions. The delimiter tells Git how to read this fetch invocation. Parser validation determines whether Docker should accept the reference for the remote-context workflow at all. Neither fact requires assuming that every later Git command has identical syntax or identical rules for ending its option list.
The new regression test supplies several malformed remote URLs and expects cloning to fail with an invalid-refspec error. Some test inputs begin the reference with option-like text. Another contains a space. The visible parser addition specifically tests the leading hyphen, so it would be inaccurate to credit that line alone with every validation behavior exercised by the complete clone test.
That is a useful distinction when reading a small security patch. A test can describe the behavior of a whole operation while the code change affects only one stage. Existing validation and Git's own errors can contribute to the final result. The evidence for the new protection is the added early rejection and the changed fetch argument construction.
Remote source selection is part of the build contract
The affected code lives under the builder's remote Git context implementation. This places the correction before the application build consumes its source context. A Dockerfile can be unchanged while the path used to obtain its contents encounters this bug. Reviewing only Dockerfile instructions therefore omits an input parser that helps establish what those instructions will mean.
Repeatability requires selecting the intended source revision, but secure source selection also requires that the selection string remain data. A repository reference has a constrained role in that process. It should identify source, without modifying the fetch program's options simply because its first character resembles an option prefix.
My preference for small final images does not reduce the importance of this earlier stage. The final application filesystem says little about how the builder interpreted the remote location that supplied its source. A build system needs both a controlled output and a correct interpretation of the inputs used to construct it.
The patch is also a useful example of preserving a reason in code review. The pull-request explanation records the possible checkout path. Without that explanation, someone examining only the new -- might conclude that the parser check duplicates it and remove the check later. Reading the two changes together shows that the validation belongs to the workflow, while the delimiter belongs to one command invocation.
Docker 18.09.4 includes this builder correction alongside runtime fixes, but the Git change has its own mechanism and scope. A reference beginning with an option prefix is rejected before the repository description is used. Accepted references reach fetch after an explicit option delimiter, including both shallow and non-shallow command forms.