Skip to content

[SSO] Fix OIDC group sync privilege escalation via case folding#36509

Open
mtabebe wants to merge 1 commit into
MaterializeInc:mainfrom
mtabebe:ma/sso/fix-lowercase
Open

[SSO] Fix OIDC group sync privilege escalation via case folding#36509
mtabebe wants to merge 1 commit into
MaterializeInc:mainfrom
mtabebe:ma/sso/fix-lowercase

Conversation

@mtabebe
Copy link
Copy Markdown
Contributor

@mtabebe mtabebe commented May 11, 2026

Problem:
JWT group names were lowercased before catalog lookup. When two roles differ only by case (e.g. admin and "Admin"), the lowercase map built by roles_by_lowercase_name silently picked the wrong role due to BTreeMap last-writer-wins semantics.

Solution:

  • remove to_lowercase() from group extraction, replace the lowercase-map lookup in sync_jwt_groups with exact try_get_role_by_name,
  • delete the now-unused roles_by_lowercase_name and try_get_role_by_name_case_insensitive methods

Testing:

  • updated three oidc.rs unit tests
  • added mzcompose workflow oidc_group_sync_case_sensitive with an OIDC mock server to verify "Admin" cannot escalate to the admin role

Remove these sections if your commit already has a good description!

Fixes: SQL-276

@mtabebe mtabebe force-pushed the ma/sso/fix-lowercase branch 4 times, most recently from ea0ef62 to b334d8c Compare May 11, 2026 17:15
@mtabebe mtabebe requested a review from SangJunBak May 11, 2026 17:33
@mtabebe mtabebe marked this pull request as ready for review May 11, 2026 17:34
@mtabebe mtabebe requested a review from a team as a code owner May 11, 2026 17:34
Comment on lines +169 to +170
// Check case-insensitively so "MZ_SYSTEM" is also blocked.
if catalog::is_reserved_role_name(&group.to_lowercase()) {
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.

I wonder if we need to check this case? Thinking the "No matching Materialize Role" warning is fine

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we should still warn as early as possible? Yes there is a false positive situation, but I feel like it is better to warn in these cases

Comment thread src/authenticator/src/oidc.rs Outdated
let groups: Vec<String> = raw_groups
.into_iter()
.map(|g| g.trim().to_lowercase())
.map(|g| g.trim().to_string())
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.

Should we still trim the groups? Given we're not normalizing anymore. E.g. there could exist a role " wee wwoo "

Copy link
Copy Markdown
Contributor Author

@mtabebe mtabebe May 12, 2026

Choose a reason for hiding this comment

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

Good catch

Problem:
JWT group names were lowercased before catalog lookup. When two roles
differ only by case (e.g. `admin` and `"Admin"`), the lowercase map
built by `roles_by_lowercase_name` silently picked the wrong role due
to BTreeMap last-writer-wins semantics.

Solution:
- remove `to_lowercase()` from group extraction, replace the
lowercase-map lookup in `sync_jwt_groups` with exact `try_get_role_by_name`,
- delete the now-unused `roles_by_lowercase_name` and
`try_get_role_by_name_case_insensitive` methods

Testing:
- updated three oidc.rs unit tests
- added mzcompose workflow `oidc_group_sync_case_sensitive` with an OIDC
mock server to verify "Admin" cannot escalate to the `admin` role
@mtabebe mtabebe force-pushed the ma/sso/fix-lowercase branch from b334d8c to 2c22d3c Compare May 12, 2026 14:55
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.

2 participants