Harden OCI registry authentication - #1278
Conversation
Validate registry-provided bearer realms, restrict cross-origin credential forwarding, and add an explicit registry-to-auth-host compatibility option. Co-authored-by: Kaniska <kaniska244@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Hardens OCI registry Bearer-token authentication by validating registry-provided realm URLs, constraining cross-origin auth host usage, disabling token-request redirects, and ensuring service/scope are encoded to prevent SSRF and credential forwarding.
Changes:
- Add realm admission + credential-forwarding policy with built-in and user-configured registry→auth-host mappings.
- Disable redirects for token endpoint requests and rebuild anonymous fallback requests to avoid replaying credentials.
- Add focused tests for realm policy, redirect refusal, and query encoding; wire the new test into CI.
Show a summary per file
| File | Description |
|---|---|
| src/spec-configuration/httpOCIRegistry.ts | Implements realm validation, cross-origin auth-host policy, credential-forwarding rules, redirect suppression for token requests, and safe URL parameter encoding. |
| src/spec-utils/httpRequest.ts | Adds a no-redirect request helper and returns responseUrl to support validating challenges against the final registry response URL. |
| src/spec-node/devContainersSpecCLI.ts | Introduces the repeatable --allow-cross-origin-auth-host <registry>=<auth> global option and propagates configuration via env. |
| src/test/httpOCIRegistry.test.ts | Adds unit/integration-style tests for realm admission, credential forwarding, redirect refusal, and query encoding behavior. |
| .github/workflows/dev-containers.yml | Adds the new test to the CI matrix and excludes it from the “run all except above” batch to avoid duplicate execution. |
Review details
Tip
Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (1)
src/spec-utils/httpRequest.ts:121
- requestResolveHeadersInternal treats any URL with hostname 'localhost' as plain HTTP, even when the URL scheme is https:. That silently downgrades https://localhost to an http request, which can break requests and can undermine scheme-based security decisions (including for token realms). Consider basing the transport strictly on the parsed protocol (and, if needed, handle localhost TLS separately).
const plainHTTP = parsed.protocol === 'http:' || parsed.hostname === 'localhost';
if (plainHTTP) {
output.write('Sending as plain HTTP request', LogLevel.Warning);
}
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
|
Companion VS Code Dev Containers integration: microsoft/vscode-remote-containers#1235 |
Propagate cross-origin auth host mappings explicitly through command, resolver, and registry request parameters instead of serializing them through the process environment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Follow-up 7b8e496 removes the internal environment-variable bridge. The option now propagates explicitly as typed command/resolver/request state across OCI paths. It also sets yargs |
Treat an exact registry-to-auth-host mapping as authorization for the complete token exchange, including Docker identity and refresh tokens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated trusted host-pair semantics in 87adb63: an exact HTTPS registry-to-auth-host mapping now authorizes both Basic and refresh/identity-token exchange. Added a real cross-authority Docker |
| it('forwards a refresh token to an explicitly configured auth host', async () => { | ||
| const token = 'registry-token'; | ||
| const refreshToken = 'registry-refresh-token'; | ||
| const bearerScheme = ['Bear', 'er'].join(''); |
There was a problem hiding this comment.
Q: Is this for preventing a credential scanner from triggering on this?
Summary
Harden OCI Feature and Template authentication against registry-controlled Bearer realms that could trigger SSRF or forward registry credentials to an attacker-selected endpoint.
This builds on the work in #1276 while narrowing the change to the authentication boundary and adding a registry-scoped compatibility escape hatch for legitimate external token services.
Session Context
Key decisions from the development session:
--allow-cross-origin-auth-host <registry-host>=<auth-host>is repeatable. A bare auth-host allowlist would let any workspace-selected registry invoke that host as a confused deputy.http://localhosttoken realms remain supported for local Feature development; remote HTTP realms remain rejected.Changes
--allow-cross-origin-auth-host <registry-host>=<auth-host>mappings for enterprise registries.serviceandscopewithURL.searchParams.Validation
yarn type-checkyarn lintyarn packageFixes github/codespaces#24328.