The goal of authentication for any given service is to verify that the user accessing the service is who they claim to be and not an impersonation. This is done by prompting the user to answer questions.
Before diving into how 2FA could be bypassed, let’s see a high-level flow of 2FA in action.
Let’s consider a scenario where James is the administrator of a web application called MyWorkApp. Alice is an employee who uses MyWorkApp.
Now that we have walked through the flow, let’s meet our attacker, Bob, who acquired Alice’s password via social engineering or other means. Bob does not have the 2FA codes that are generated in Alice’s phone, and without them, Bob should not be able to take over Alice’s account.
MyWorkApp, however, has a misconfiguration that allows more than one device to be configured for 2FA purposes. This means Alice can have 2FA set up with the same code generator running on two or more phones/devices. Bob uses this information to exploit the application in the following manner:
Bob was able to gain control over the Alice’s OTP generator because
The 2FA is likely to present the same QR code because it is coupled with the same user.
A secure implementation of a 2FA setup should check for a user’s authenticity before initiating a critical response such as the QR code for generating the tokens. A user setting up 2FA for the first time should receive backup codes that can be used alternatively to the generated tokens. These codes will serve as a backup if the user loses access to the device used to generate the tokens. If the application detects a valid backup code, it could prompt the user to disable the previously set device and enroll a new one. The application should also send a notification to the user when an unrecognized login occurs. Any user actions that change the state of the system or the user profile must be controlled and validated on the server side.