Skip to content

Cannot read field "verified" because "<local1>" is null (NPE in TwoFactorEnableCompleteAction → BaseOAuthAction) #2474

@wproffitt-elder

Description

@wproffitt-elder

Cannot read field "verified" because "" is null (NPE in TwoFactorEnableCompleteAction → BaseOAuthAction)

Description

ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown
java.lang.NullPointerException: Cannot read field "verified" because "<local1>" is null
	at io.fusionauth.app.action.oauth2.BaseOAuthAction.next(BaseOAuthAction.java:913)
	at io.fusionauth.app.action.oauth2.TwoFactorEnableCompleteAction.post(TwoFactorEnableCompleteAction.java:42)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.primeframework.mvc.util.ReflectionUtils.invoke(ReflectionUtils.java:443)
	at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.execute(DefaultActionInvocationWorkflow.java:77)
	at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.perform(DefaultActionInvocationWorkflow.java:60)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:50)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:45)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:60)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:49)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:74)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:58)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:92)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:50)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:119)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:65)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.cors.CORSRequestWorkflow.perform(CORSRequestWorkflow.java:65)
	at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
	at org.primeframework.mvc.workflow.DefaultMVCWorkflow.perform(DefaultMVCWorkflow.java:108)
	at org.primeframework.mvc.PrimeMVCRequestHandler.handle(PrimeMVCRequestHandler.java:72)
	at io.fusionauth.http.server.HTTPWorker.run(HTTPWorker.java:50)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

Under certain conditions when a user is trying to complete two-factor authentication setup (in our case with a QR code for TOTP), this NPE can trigger on the back end, and to an end user, it appears as this message:

We're sorry, your request was malformed or was unable to be completed for some reason. Try hitting the back button and restarting the process to see if it fixes the problem.

Hitting the back button does not provide a graceful resolution, but the two-factor authentication setup does complete successfully and the user can login if they start the login process all over again.

What did fix the problem for us overall so that this NPE didn't trigger anymore is enabling "Require registration" under OAuth settings for the given application. Unfortunately, this solution was not obvious and we happened upon it by trying things.

Affects versions

1.47.1.

Steps to reproduce

The following was true of our deployment as part of the initial setup that led to this:

  1. Created a new tenant.
  2. Turned on tenant-level requirement for users to use multi-factor authentication each login.
  3. Created an application associated with the tenant.
  4. Turned and set up SAML for the application.

From there, we created a new test user for the tenant and had them attempt to log in to the application for the first time, which prompted the two-factor authentication initial setup which then ended with the generic user-facing error and the NPE in the logs.

Severity

Since the issue is resolvable by turning on "Require registration", we haven't found it to be a showstopper, but for someone with less troubleshooting time on their hands, it could be.

Without figuring out the work around, we would have been looking at a situation where we advise every new user of our application something along the lines of "at this point you'll see an error message, but don't worry, it probably actually worked, and you can now log in using your password and 6-digit rotating code if you return to the log in page at the above URL".

Expected behavior

With "require registration" turned off, my expectation would be for the two-factor setup to work without this error and for the user to then complete the flow by reaching the application which they can then access with or without a registration.

Release Notes

Resolve an issue where users could not enable two-factor authentication during authentication when they were not registered for the application. Thanks to https://github.com/wproffitt-elder[@wproffitt-elder] for reporting!

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Delivered

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions