Validate import URL security after credential injection
What does this MR do?
Reorders ensure_auth_credentials! before validate_url_security! in Import::ValidateRemoteGitEndpointService so the SSRF check validates the final URL (with credentials embedded) that will be sent to Gitaly, not just the base URL.
Adds a defense-in-depth hostname comparison in ensure_auth_credentials! that raises BlockedUrlError if injecting credentials into the URI changes the target hostname (e.g. through URI parsing quirks or encoding changes).
Why
The SSRF check previously ran on the URL before credentials were injected. A malicious username/password (e.g. user: '127.0.0.1', password: '3333/mypath#') could alter the effective host of the final URL, bypassing the validation.
The immediate attack vector is already neutralized by the percent-encoding added in Fix import_url validation for passwords with sp... (!232440 - merged) (CGI.escape encodes # as %23, / as %2F, etc.), but the call ordering was still wrong: the security check should always see the actual URL used for the connection. This MR fixes the ordering and adds hostname-change detection as a safety net.
Existing mitigation status
The percent-encoding fix (7ce772a9) that inadvertently neutralizes the attack has already shipped in all supported versions:
| Branch | First version with fix | Latest patch | Commit |
|---|---|---|---|
| master | v19.0.0-ee | v19.0.1-ee | 7ce772a9 |
| 18-11-stable | v18.11.4-ee | v18.11.4-ee | backport-343452-fix-import-url-validation-18-11 |
| 18-10-stable | v18.10.7-ee | v18.10.7-ee | backport-343452-fix-import-url-validation-18-10 |
| 18-9-stable | v18.9.7-ee | v18.9.8-ee | backport-343452-fix-import-url-validation-18-9 |
This MR adds correct call ordering and defense-in-depth on top of the existing fix.