Having 2 factor checked only at login is a security issue. Please consider following MtGox's lead and properly secure withdraws with an explicity authentication.
Having 2 factor at login is "good" (certainly better than no 2 factor) but it still leaves the user vulnerable to session jacking where the attacker can impersonate the already authenticated user. For sites that allow 2factor to be disabled from an authenticated session without a final 2factor verification a simpler attack is possible where the attacker simply disables 2factor from an active session and locks the user out.
Example session jacking attack:
User who has a strong password and OATH (2factor) device logs into exchange. User is prompted for 2factor code, and authenticated. Unknown to the user his system is compromised and is monitoring browsing activity looking for logins. The trojan notifies the attacker that the user has an authenticated session. Attacker uses the trojan and authenticated session to exchange all USD for BTC and withdraw all BTC to attacker's address. This action can be nearly invisible to the user. The user's session is stolen and the attacker impersonates the user when making the withdraw. To the exchange server everything appears as genuine browser actions from an authenticated user from their IP address. The speed of the attack is only limited by the exchange servers processing. The user can be logged in looking at $18,000 USD and 2,000 BTC and then an AJAX refresh occurs and user is looking at $0 USD and 0 BTC. Looking in the activity history the user will see trades and withdraws that occurred seconds prior which appear to have come from him.
Eventually this WILL happen; it isn't a matter of if but when. When that happens it will undermine confidence in users. "See even WITH strong passwords AND 2 factor AND a reputable exchange with partial cold storage you can still lose everything in a second".
MtGox's setup with a complete security center and ability to configure multiple OATH devices for various options is ideal but it is also a lot for a smaller exchange to take on.
The simplest fix (more like a patch) is to just limit 2factor to withdraws (and removing/updating 2 factor and editing/adding pre-saved withdraw options). Obviously changing 2factor should always require 2 factor verification. While in theory if 2factor is limited to just withdraws an attacker could force a user to sell (and attacker ensure he has the highest bid) however max loss would be the % difference in the bid ask spread. (i.e. user sells $1,000 worth of BTC and only gets $997 worth of USD). It is a pretty weak attack vector and certainly less profitable than session jacking. The largest attack vector is removing funds from the exchange account moving the 2factor to that action hardens it.
A better solution would be to have multiple choices on 2factor configuration page.
- No 2 factor
- 2 factor on withdraw
- 2 factor on login
- 2 factor on login & withdraw