Skip to content

CXH-2349: harden account hostname resolution - #59

Open
al-conductorone wants to merge 2 commits into
mainfrom
cxh-2349-hostname-resolution-hardening
Open

CXH-2349: harden account hostname resolution#59
al-conductorone wants to merge 2 commits into
mainfrom
cxh-2349-hostname-resolution-hardening

Conversation

@al-conductorone

Copy link
Copy Markdown
Contributor

The Databricks connector no longer mistakes a look-alike domain for the real Azure or GCP host when it works out the account address, closing a spoofing gap. Behaviour is unchanged for legitimate hostnames.

Match azure/gcp host suffixes on a DNS label boundary so look-alike
domains (e.g. evilazuredatabricks.net) no longer resolve to the Azure
account host. Drop the unused defaultHost const and document the AWS
fall-through as deliberate.
@linear-code

linear-code Bot commented Aug 28, 2026

Copy link
Copy Markdown

CXH-2349

Comment thread pkg/databricks/client.go
// label boundary. Plain strings.HasSuffix would let evilazuredatabricks.net
// match azuredatabricks.net; requiring the leading dot prevents that.
func hostMatches(hostname, suffix string) bool {
return hostname == suffix || strings.HasSuffix(hostname, "."+suffix)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: hostMatches is case-sensitive, but DNS hostnames are not — a config value like MyOrg.AzureDatabricks.net (or a trailing-dot FQDN) falls through to the default branch and yields accounts.MyOrg.AzureDatabricks.net instead of the canonical Azure account host. The failure is fail-safe rather than a spoofing bypass, but since this function's job is host classification it's worth normalising first, e.g. hostname = strings.ToLower(strings.TrimSuffix(hostname, ".")) in GetAccountHostname before matching.

Comment thread pkg/databricks/client.go
Comment on lines +65 to +68
default:
// AWS and unknown hosts have no canonical account suffix to normalise to,
// so prefix the host as given.
return "accounts." + hostname

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The comment is inaccurate for AWS — AWS does have a canonical account host (accounts.cloud.databricks.com), which is exactly the defaultHost constant this PR deletes. Real AWS workspace hostnames look like dbc-1234abcd.cloud.databricks.com, so this branch produces accounts.dbc-1234abcd.cloud.databricks.com, which is not a valid account endpoint (the added test encodes this as "aws falls through unnormalised"). This is pre-existing behaviour and users can work around it with --account-hostname, so not blocking, but consider keeping defaultHost = "cloud.databricks.com" and adding a third hostMatches(hostname, defaultHost) case for symmetry with Azure/GCP; at minimum reword the comment so it doesn't claim AWS has no canonical suffix.

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: CXH-2349: harden account hostname resolution

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base ef6c2aae70ca.
Review mode: incremental since 0fa67d68
View review run

Review Summary

The full PR diff was scanned for security and correctness; the new commit touches only pkg/databricks/client.go and its test. Both prior findings are addressed: GetAccountHostname now lowercases the hostname and strips a trailing dot before matching, so MyOrg.AzureDatabricks.net and myorg.azuredatabricks.net. normalise correctly, and the restored AWS defaultHost case resolves workspace hosts such as dbc-1234abcd.cloud.databricks.com to accounts.cloud.databricks.com instead of the previously invalid accounts.dbc-1234abcd.cloud.databricks.com. The label-boundary check in hostMatches still rejects lookalikes like evilazuredatabricks.net, the new table-driven cases cover every branch, and an explicit account-hostname config value still short-circuits the calculation, so no new issues were found.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

Comment thread pkg/databricks/client.go
// label boundary. Plain strings.HasSuffix would let evilazuredatabricks.net
// match azuredatabricks.net; requiring the leading dot prevents that.
func hostMatches(hostname, suffix string) bool {
return hostname == suffix || strings.HasSuffix(hostname, "."+suffix)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi / out of scope: this is still case-sensitive — MyOrg.AzureDatabricks.NET falls through instead of hitting azure. pre-existing under HasSuffix, not blocking this PR.

Comment thread pkg/databricks/client.go
// label boundary. Plain strings.HasSuffix would let evilazuredatabricks.net
// match azuredatabricks.net; requiring the leading dot prevents that.
func hostMatches(hostname, suffix string) bool {
return hostname == suffix || strings.HasSuffix(hostname, "."+suffix)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi / out of scope: trailing FQDN dot (….azuredatabricks.net.) also misses. atypical input, not blocking.

Comment thread pkg/databricks/client.go Outdated
return "accounts." + gcpHost
default:
// AWS and unknown hosts have no canonical account suffix to normalise to,
// so prefix the host as given.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: AWS does have a canonical account host (accounts.cloud.databricks.com). maybe rephrase — something like workspace AWS hosts stay prefixed as-is on purpose, rather than "no canonical suffix"?

Lowercase and trim a trailing root dot in GetAccountHostname so mixed-case
or dotted Azure/GCP hosts resolve to the right account host instead of
falling through. Restore the AWS defaultHost so workspace hosts like
dbc-1234.cloud.databricks.com resolve to accounts.cloud.databricks.com
rather than an invalid accounts.dbc-1234... endpoint.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants