Prevent usernames from acting as permission wildcards - #27379
Open
dennisoelkers wants to merge 3 commits into
Open
dennisoelkers wants to merge 3 commits into
dennisoelkers wants to merge 3 commits into
Conversation
Every non-service-account user implicitly receives self-service
permissions built by string concatenation:
users:edit:<username>, users:passwordchange:<username>, ...
Those strings are parsed as Shiro wildcard permissions, where "*" matches
anything and "," separates alternatives. Usernames were only length
checked, so a user named "*" held users:edit:* and
users:passwordchange:* over every other account, and a user named
"admin,attacker" held them over "admin". The same concatenation is used
when a grant target is turned into a Shiro permission, so the entity ID of
a grant had the same problem.
Two ways in: a holder of users:create makes such a user and logs in as
it, or an authentication service supplies the name, since provisioning
copies the external username verbatim. PrivilegeEscalationGuard does not
see these implicit permissions, so neither path is caught.
Fixed in two layers:
- PermissionInstances#isSafe rejects identifiers that do not address a
single instance. Permissions#userSelfEditPermissions grants nothing
for such a username and DomainActionPermission#toShiroPermission
returns a permission that implies nothing, so accounts already stored
with such a name are harmless without a migration.
- UsernameValidator rejects these names on save, which covers user
creation, updates and authentication service provisioning alike.
Note this is a behaviour change for deployments that use an identifier
containing "," or ":" as the username attribute, for example a full LDAP
DN. Those accounts keep working but lose the implicit self-service
permissions, and saving them fails until they are renamed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Motivation and Context
Every non-service-account user implicitly receives self-service permissions built by string concatenation:
Those strings are parsed as Shiro wildcard permissions, where "" matches anything and "," separates alternatives. Usernames were only length checked, so a user named "" held users:edit:* and
users:passwordchange:*over every other account, and a user named "admin,attacker" held them over "admin". The same concatenation is used when a grant target is turned into a Shiro permission, so the entity ID of a grant had the same problem.Two ways in: a holder of
users:createmakes such a user and logs in as it, or an authentication service supplies the name, since provisioning copies the external username verbatim.PrivilegeEscalationGuarddoes not see these implicit permissions, so neither path is caught.Fixed in two layers:
PermissionInstances#isSaferejects identifiers that do not address a single instance.Permissions#userSelfEditPermissionsgrants nothing for such a username andDomainActionPermission#toShiroPermissionreturns a permission that implies nothing, so accounts already stored with such a name are harmless without a migration.UsernameValidatorrejects these names on save, which covers user creation, updates and authentication service provisioning alike.Note this is a behaviour change for deployments that use an identifier containing "," or ":" as the username attribute, for example a full LDAP DN. Those accounts keep working but lose the implicit self-service permissions, and saving them fails until they are renamed.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: