Default behavior
In a standard spring boot application with spring security this matches when the user is anonymous because the user has been given the ROLE_ANONYMOUS and the default prefix is ROLE_.
@PreAuthorize("hasRole('ANONYMOUS')")
My context
In my project I have a custom Bean that forces a non-standard (randomized) role prefix. I do this to reduce what I see as a possible attack vector.
Simplified I have:
@Bean
fun grantedAuthorityDefaults(): GrantedAuthorityDefaults {
return GrantedAuthorityDefaults("SOMETHING_DIFFERENT_")
}
Bug description
What I found is that in many places in the Spring Security codebase the role prefix for the ANONYMOUS role has been hardcoded to ROLE_.
I see in many places code similar to this
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
Since the above mentioned @PreAuthorize("hasRole('ANONYMOUS')") expression actually checks using the custom prefix for SOMETHING_DIFFERENT_ANONYMOUS, this will no longer match the actually present ROLE_ANONYMOUS.
Workaround?
I now have custom code that adds an "ANONYMOUS" role with the configured prefix (which can be anything including the default "ROLE_") to the list of authorities.
This overrules the default functionality and now it works again... in the test cases I tried. I'm NOT sure I have covered all cases with this.
http
.anonymous { it.authorities(listOf(SimpleGrantedAuthority("${grantedAuthorityDefaults.rolePrefix}ANONYMOUS")))
Default behavior
In a standard spring boot application with spring security this matches when the user is anonymous because the user has been given the
ROLE_ANONYMOUSand the default prefix isROLE_.@PreAuthorize("hasRole('ANONYMOUS')")My context
In my project I have a custom Bean that forces a non-standard (randomized) role prefix. I do this to reduce what I see as a possible attack vector.
Simplified I have:
Bug description
What I found is that in many places in the Spring Security codebase the role prefix for the
ANONYMOUSrole has been hardcoded toROLE_.I see in many places code similar to this
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");Since the above mentioned
@PreAuthorize("hasRole('ANONYMOUS')")expression actually checks using the custom prefix forSOMETHING_DIFFERENT_ANONYMOUS, this will no longer match the actually presentROLE_ANONYMOUS.Workaround?
I now have custom code that adds an "ANONYMOUS" role with the configured prefix (which can be anything including the default "ROLE_") to the list of authorities.
This overrules the default functionality and now it works again... in the test cases I tried. I'm NOT sure I have covered all cases with this.
http .anonymous { it.authorities(listOf(SimpleGrantedAuthority("${grantedAuthorityDefaults.rolePrefix}ANONYMOUS")))