Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Serializable Security Components declare serialVersionUID #16276

Open
jzheaux opened this issue Dec 13, 2024 · 1 comment
Open

Ensure Serializable Security Components declare serialVersionUID #16276

jzheaux opened this issue Dec 13, 2024 · 1 comment
Assignees
Labels
in: core An issue in spring-security-core type: bug A general bug
Milestone

Comments

@jzheaux
Copy link
Contributor

jzheaux commented Dec 13, 2024

To ensure backward compatibility, Security components that implement Serializable should have a serialVersionUID.

Based on internal testing across a few dozen JVMs, it appears that the serialVersionUID is consistent for Security's components. As such, we can safely add the calculated serialVersionUID value to each class that is missing it during the 6.4.x maintenance cycle.

When addressing a class that is missing its serialVersionUID, please do the following:

  1. Add the calculated serialVersionUID (IDEs can usually do this for you, or you can use serialver which ships with the JVM)

  2. In SpringSecurityCoreVersionSerializableTests, add the class and an example construction to the generatorByClassName map

  3. Run SpringSecurityCoreVersionSerializableTests#serializeCurrentVersionClasses.

  4. If successful, it will create a {className}.serialized file in config/src/main/resources/serialized:

    Run the other tests in SpringSecurityCoreVersionSerializableTests; because it's new, the class will not be added to the list in shouldBeAbleToDeserializeClassFromPreviousVersion; however, the class should no longer be in the output for listClassesMissingSerialVersion

    Commit the Serialiizable class(es) and SpringSecurityCoreVersionSerializableTests

  5. If unsuccessful, it is usually because one of its members is not serializable. Find the unserializable member; file a ticket to ensure that it is made Serializable

Here are the classes:

  • org.springframework.security.cas.jackson2.CasJackson2Module
  • org.springframework.security.saml2.Saml2Exception
  • org.springframework.security.saml2.jackson2.Saml2Jackson2Module
  • org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException
  • org.springframework.security.web.access.expression.WebExpressionConfigAttribute
  • org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException
  • org.springframework.security.web.authentication.rememberme.CookieTheftException
  • org.springframework.security.web.authentication.rememberme.InvalidCookieException
  • org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException
  • org.springframework.security.web.authentication.session.SessionAuthenticationException
  • org.springframework.security.web.authentication.session.SessionFixationProtectionEvent
  • org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent
  • org.springframework.security.web.authentication.www.NonceExpiredException
  • org.springframework.security.web.csrf.CsrfException
  • org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler$SupplierCsrfToken
  • org.springframework.security.web.csrf.DefaultCsrfToken
  • org.springframework.security.web.csrf.InvalidCsrfTokenException
  • org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken
  • org.springframework.security.web.csrf.MissingCsrfTokenException
  • org.springframework.security.web.firewall.RequestRejectedException
  • org.springframework.security.web.jackson2.WebJackson2Module
  • org.springframework.security.web.jackson2.WebServletJackson2Module
  • org.springframework.security.web.savedrequest.SimpleSavedRequest
  • org.springframework.security.web.server.authentication.SwitchUserWebFilter$SwitchUserAuthenticationException
  • org.springframework.security.web.server.csrf.CsrfException
  • org.springframework.security.web.server.csrf.DefaultCsrfToken
  • org.springframework.security.web.server.firewall.ServerExchangeRejectedException
  • org.springframework.security.web.server.jackson2.WebServerJackson2Module
  • org.springframework.security.web.session.HttpSessionCreatedEvent
  • org.springframework.security.web.session.HttpSessionDestroyedEvent
  • org.springframework.security.web.session.HttpSessionIdChangedEvent
  • org.springframework.security.web.session.SessionInformationExpiredEvent
  • org.springframework.security.web.webauthn.authentication.WebAuthnAuthentication
  • org.springframework.security.web.webauthn.authentication.WebAuthnAuthenticationRequestToken
  • org.springframework.security.web.webauthn.jackson.AttestationConveyancePreferenceSerializer
  • org.springframework.security.web.webauthn.jackson.AuthenticationExtensionsClientInputSerializer
  • org.springframework.security.web.webauthn.jackson.AuthenticationExtensionsClientInputsSerializer
  • org.springframework.security.web.webauthn.jackson.AuthenticationExtensionsClientOutputsDeserializer
  • org.springframework.security.web.webauthn.jackson.AuthenticatorAttachmentDeserializer
  • org.springframework.security.web.webauthn.jackson.AuthenticatorAttachmentSerializer
  • org.springframework.security.web.webauthn.jackson.AuthenticatorTransportDeserializer
  • org.springframework.security.web.webauthn.jackson.BytesSerializer
  • org.springframework.security.web.webauthn.jackson.COSEAlgorithmIdentifierDeserializer
  • org.springframework.security.web.webauthn.jackson.COSEAlgorithmIdentifierSerializer
  • org.springframework.security.web.webauthn.jackson.CredProtectAuthenticationExtensionsClientInputSerializer
  • org.springframework.security.web.webauthn.jackson.DurationSerializer
  • org.springframework.security.web.webauthn.jackson.PublicKeyCredentialTypeDeserializer
  • org.springframework.security.web.webauthn.jackson.PublicKeyCredentialTypeSerializer
  • org.springframework.security.web.webauthn.jackson.ResidentKeyRequirementSerializer
  • org.springframework.security.web.webauthn.jackson.UserVerificationRequirementSerializer
  • org.springframework.security.web.webauthn.jackson.WebauthnJackson2Module
  • org.springframework.security.oauth2.core.OAuth2AuthenticationException
  • org.springframework.security.oauth2.core.OAuth2AuthorizationException
  • org.springframework.security.access.AccessDeniedException
  • org.springframework.security.access.AuthorizationServiceException
  • org.springframework.security.access.SecurityConfig
  • org.springframework.security.access.annotation.Jsr250SecurityConfig
  • org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent
  • org.springframework.security.access.event.AuthorizationFailureEvent
  • org.springframework.security.access.event.AuthorizedEvent
  • org.springframework.security.access.event.PublicInvocationEvent
  • org.springframework.security.access.expression.method.PostInvocationExpressionAttribute
  • org.springframework.security.access.expression.method.PreInvocationExpressionAttribute
  • org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor
  • org.springframework.security.authentication.AccountExpiredException
  • org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
  • org.springframework.security.authentication.AuthenticationServiceException
  • org.springframework.security.authentication.BadCredentialsException
  • org.springframework.security.authentication.CredentialsExpiredException
  • org.springframework.security.authentication.DisabledException
  • org.springframework.security.authentication.InsufficientAuthenticationException
  • org.springframework.security.authentication.InternalAuthenticationServiceException
  • org.springframework.security.authentication.LockedException
  • org.springframework.security.authentication.ProviderNotFoundException
  • org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent
  • org.springframework.security.authentication.event.AuthenticationFailureCredentialsExpiredEvent
  • org.springframework.security.authentication.event.AuthenticationFailureDisabledEvent
  • org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent
  • org.springframework.security.authentication.event.AuthenticationFailureLockedEvent
  • org.springframework.security.authentication.event.AuthenticationFailureProviderNotFoundEvent
  • org.springframework.security.authentication.event.AuthenticationFailureProxyUntrustedEvent
  • org.springframework.security.authentication.event.AuthenticationFailureServiceExceptionEvent
  • org.springframework.security.authentication.event.AuthenticationSuccessEvent
  • org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
  • org.springframework.security.authentication.event.LogoutSuccessEvent
  • org.springframework.security.authentication.jaas.event.JaasAuthenticationFailedEvent
  • org.springframework.security.authentication.jaas.event.JaasAuthenticationSuccessEvent
  • org.springframework.security.authentication.ott.InvalidOneTimeTokenException
  • org.springframework.security.authentication.password.CompromisedPasswordException
  • org.springframework.security.authorization.AuthorizationDeniedException
  • org.springframework.security.authorization.event.AuthorizationDeniedEvent
  • org.springframework.security.authorization.event.AuthorizationEvent
  • org.springframework.security.authorization.event.AuthorizationGrantedEvent
  • org.springframework.security.core.ComparableVersion$ListItem
  • org.springframework.security.core.context.SecurityContextChangedEvent
  • org.springframework.security.core.context.TransientSecurityContext
  • org.springframework.security.core.session.AbstractSessionEvent
  • org.springframework.security.core.userdetails.UsernameNotFoundException
  • org.springframework.security.jackson2.CoreJackson2Module
  • org.springframework.security.jackson2.SecurityJackson2Modules$AllowlistTypeResolverBuilder
  • org.springframework.security.access.annotation.BusinessServiceImpl
  • org.springframework.security.access.annotation.ExpressionProtectedBusinessServiceImpl
  • org.springframework.security.access.annotation.Jsr250BusinessServiceImpl
  • org.springframework.security.crypto.codec.Base64$InvalidBase64CharacterException
  • org.springframework.security.ldap.authentication.ad.ActiveDirectoryAuthenticationException
  • org.springframework.security.ldap.jackson2.LdapJackson2Module
  • org.springframework.security.ldap.ppolicy.PasswordPolicyControl
  • org.springframework.security.ldap.ppolicy.PasswordPolicyException
  • org.springframework.security.ldap.ppolicy.PasswordPolicyResponseControl
  • org.springframework.security.messaging.access.expression.MessageExpressionConfigAttribute
  • org.springframework.security.oauth2.client.ClientAuthorizationException
  • org.springframework.security.oauth2.client.ClientAuthorizationRequiredException
  • org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module
  • org.springframework.security.oauth2.client.web.InvalidClientRegistrationIdException
  • org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter$OAuth2AuthorizationRequestException
  • org.springframework.security.oauth2.jwt.BadJwtException
  • org.springframework.security.oauth2.jwt.JwtDecoderInitializationException
  • org.springframework.security.oauth2.jwt.JwtEncodingException
  • org.springframework.security.oauth2.jwt.JwtException
  • org.springframework.security.oauth2.jwt.JwtValidationException
  • org.springframework.security.oauth2.server.resource.InvalidBearerTokenException
  • org.springframework.security.oauth2.server.resource.introspection.BadOpaqueTokenException
  • org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException

You can also see the list of Serializable files by running:

./gradlew :spring-security-config:test --tests "*MissingSerialVersion*" -Pserialization
@jzheaux jzheaux added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Dec 13, 2024
jzheaux added a commit that referenced this issue Dec 13, 2024
jzheaux added a commit that referenced this issue Dec 13, 2024
This allows testing of classes that are serializable,
but do not use Security's serialVersionUID.

Issue gh-16276
jzheaux added a commit that referenced this issue Dec 13, 2024
@jzheaux
Copy link
Contributor Author

jzheaux commented Dec 13, 2024

Here is an example: e3cd433

jzheaux added a commit to jzheaux/spring-security that referenced this issue Dec 13, 2024
jzheaux added a commit to jzheaux/spring-security that referenced this issue Dec 13, 2024
jzheaux added a commit that referenced this issue Dec 13, 2024
jzheaux added a commit that referenced this issue Dec 14, 2024
The following inner classes are used only internally by a non-Serializable component

Issue gh-16276
@jzheaux jzheaux self-assigned this Dec 17, 2024
@jzheaux jzheaux added this to the 6.4.x milestone Dec 17, 2024
@jzheaux jzheaux added in: core An issue in spring-security-core type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core An issue in spring-security-core type: bug A general bug
Projects
Status: No status
Development

No branches or pull requests

1 participant