Skip to content

fix: a default profile is one the administrator could have assigned - #914

Merged
blaipr merged 1 commit into
mainfrom
fix/a-default-profile-is-one-the-admin-could-assign
Sep 7, 2026
Merged

fix: a default profile is one the administrator could have assigned#914
blaipr merged 1 commit into
mainfrom
fix/a-default-profile-is-one-the-admin-could-assign

Conversation

@blaipr

@blaipr blaipr commented Sep 7, 2026

Copy link
Copy Markdown
Member

Three doors set the profile a user is auto-provisioned into, and none of them asked whether the
administrator setting it could have granted that profile by hand.

UserProfileService::assertAssignableBy() is the check: unless you are isAdminApp, you cannot
assign a profile that grantsBeyond() your own. Every user create/edit door already calls it — both
web save controllers and both API ones, six call sites. These three did not:

door what it sets had USER_CREATE had assignability
ConfigLdap\ImportController the profile every imported user is created with yes no
ConfigLdap\SaveController ldapDefaultProfile, read by User::createOnLogin() for every future LDAP sign-in yes no
ConfigAuth\SaveController ssoDefaultProfile, the same for SSO no no

CONFIG_LDAP and CONFIG_GENERAL answer isConfigGeneral(); USER_CREATE answers isMgmUsers().
Those are independent profile bits, so a delegated administrator holding both — an ordinary
arrangement — could name a profile stronger than their own and have every directory or SSO user
provisioned into it. USER_CREATE answers "may create users at all"; it says nothing about how much
a particular profile grants, which is the whole point of the other check.

The SSO door is the weakest of the three: it had neither half, so isConfigGeneral() alone was
enough. It now guards both, and only when the settings actually change — copied from
ConfigLdap\SaveController, so an administrator of the rest of the page can still save it.

Tests

Four, one per gap, each with a UserProfileService whose assertAssignableBy() refuses:

  • naming a stronger profile as the LDAP default is refused;
  • importing users into a stronger profile is refused;
  • changing the SSO defaults without USER_CREATE is refused;
  • naming a stronger SSO profile is refused.

Mutation-verified: reverting src/ fails all four and nothing else.

Three doors set the profile a user is auto-provisioned into, and none asked whether the
administrator setting it could have granted that profile by hand.
UserProfileService::assertAssignableBy() is that check, and every user create/edit door
already calls it — six call sites across web and API.

ConfigLdap's import and save had USER_CREATE but not assignability; ConfigAuth's save, which
sets ssoDefaultProfile for every SSO auto-provisioned user, had neither. CONFIG_LDAP and
CONFIG_GENERAL answer isConfigGeneral() while USER_CREATE answers isMgmUsers() — independent
bits — so a delegated administrator holding both could name a profile stronger than their own
and have every directory or SSO user provisioned into it. USER_CREATE is 'may create users at
all'; it says nothing about how much a particular profile grants.

The SSO guard fires only when the settings change, copied from ConfigLdap's, so an
administrator of the rest of that page can still save it.
@blaipr
blaipr merged commit 1be43fc into main Sep 7, 2026
8 checks passed
@blaipr
blaipr deleted the fix/a-default-profile-is-one-the-admin-could-assign branch September 7, 2026 23:07
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.

1 participant