Is there a way to prevent hackers from using cookies to bypass two step verification?
Matthew's answer is definitely the correct answer, but I thought I'd follow up with more details:
Cookie-based authentication has a big weakness - the cookie is all you need to authenticate. If someone is able to steal a user's cookie, there is nothing built into the cookie authentication process that let's the server know that shenanigans have happened. You use the example of an attacker having physical access to the computer, but that is a rare case to look out for. XSS vulnerabilities on sites with insecure cookies are a far more common way for cookies to get stolen. Also common: session fixation attacks, packet sniffing over insecure wireless networks for sites that don't use https, and various other forms of MITM attacks. To be clear, this isn't just an issue for cookie-based authentication. The underlying problem is that HTTP is a stateless protocol, which means that if you can replay a previous request completely, there is no way (baked into HTTP) for the server to know that you are not the same person.
So how do services make sure that the person they talk to are the person they actually want to talk to? The answer is not necessarily straight-forward. As Matthew mentions, you have to monitor your access credentials in other ways: IP address changes, browser changes, user agent changes, etc... In essence you keep track of meta data related to the devices you are talking to and take close attention to any suspicious changes.
As you note in a comment, even this isn't fool-proof. People can obviously fake user-agents. This could possibly be countered by using device fingerprinting techniques (Device fingerprinting & Mass Computer Surveillance) which an attacker has substantially less control over. IP Addresses aren't fixed, especially for mobile carriers, but as long as each device has it's own cookie, even this can potentially be tracked and accounted for. If a given cookie has been associated with the same IP address for 6 months and is suddenly showing up in another country, you probably have a problem. If a device frequently changes IP addresses (i.e. a phone) but now shows up with an IP address not associated with a mobile carrier or their usual geographic area, you probably have a problem. The other thing to keep in mind is that each device should have a unique cookie. Therefore, even if the IP address associated with a cookie normally changes, if you are now receiving requests from that cookie from two different IP addresses at the same time, you probably have a problem.
In the end, the simplest way to fix things if their appears to be something fishy going on is to simply invalidate all cookies (aka log the user out). The legitimate user is only slightly inconvenienced - they just have to log back in. The attacker though has lost all access and has to start over.
The take away
There should be a couple obvious takeaways from the above discussion:
- There is no definite answer. A sufficiently smart attacker has lots of ways to try to hide that he has stolen credentials, once they are stolen.
- A system that hasn't setup extensive security/monitoring around their login credentials will have no way to know that something is going on, and no way to react.
- There is no clear "Okay, you are secure now" point. There is a lot that a system can do to secure login credentials, but ultimately there are things not under the server's control that can allow credentials to be stolen. There are ways to detect stolen credentials, but they are not always easy or straight-forward and can take a lot of effort to setup, tune, and use. It is also possible to be overzealous and cause problems for legitimate users.
So how do the big guys minimize the potential damage done from people walking away with credentials? Short answer: Defense in depth. Secure access credentials at all layers of the application, monitor meta data from clients using access credentials, and if in doubt, log them out.
The basic method is to change cookie on a fairly regular basis - make it so that an attacker who obtains a cookie from your computer only has a limited period where it is valid. Even if the session is kept open for a longer time, you can replace the cookie which is associated with the session on a more regular basis.
In order to detect this type of abuse, services can also provide a list of active sessions, associated with IP address/device type/etc. This allows users to see if there are unexpected sessions open, and to close these.
It's also a good idea to ask for a second factor for every important action within the application (as @Xavier59 mentioned in comment) - these could be things like changing the password, changing the associated email address, or attempting to turn off 2FA.