Pages:
Author

Topic: A concise 2FA/TOTP implementation (SMF patch) (Read 1661 times)

legendary
Activity: 1148
Merit: 3117
Hey Rick. Sorry for taking so long to get back to you. I get what you're referring to, but, I don't know... I don't think recovery codes make that much sense for this implementation (in terms of value added vs. complexity added). There's already a worked-out mechanism for recovering access to your account if you lose your 2FA app/device (just do an e-mail based password reset and check the appropriate box). I guess, if people would really rather avoid doing a password reset, then, what they could do (though I don't recommend it, not unless they really know what they're doing) is keep a copy of their Base32-encoded secret somewhere, and then, if the need arises, they could either import that into something that easily accepts Base32 secrets, like KeePassXC, or they could paste/place it into the above script and (either way) then generate the OTPs necessary to get back into their account and disable 2FA (before presumably re-enabling it with a different/fresh shared secret).
Thank you for your concise reply. I totally understand your perspective, especially considering the fact that there is already a backup solution - in means of e-mail password reset - and that it would complicate the code further. In my mind I had the expectations that perhaps it would just be a case of inserting an already existing slice of code into the main body of SMFs code to generate those recovery codes associated with the secret. Considering that it isn't the case, and the fact that you make these improvements on your own free time, it doesn't justify the trouble...
hero member
Activity: 510
Merit: 4005
1) does turning on 2FA supersede the Security Question and disable it from being able to be deleted ?
To the first part of the question: 2FA operates independently of the secret question/answer feature (that is, the two features live side-by-side and don't interact with each other, at least not directly; see the next bit).

To the second part of the question: Yep, kind of. When 2FA is enabled, changes to your account settings require both your password (as before) and a valid OTP. So, someone wouldn't be able to, for example, go mess with your secret question/answer, even if they found your account in an already-logged-in state and knew your password (because they presumably wouldn't be able to produce a valid OTP and would run into the daily retry-limit).

N.B. I'm not sure how many people are aware of this, but, assuming it still works the same way it did when I last looked into it, then, the secret question/answer feature really shouldn't be used. The modified implementation of it that this forum uses bears little resemblance (logic-wise) to the original SMF feature: it no longer operates in the way most users would expect (the slightly inaccurate/misleading cautionary text on the account-settings page doesn't help), and while it can succeed in resetting your password (but not your 2FA), in that case, it will also lock you out of the account and mark it for manual review/recovery (like I said, don't use it: it's mostly just a footgun at this point).

2) jw ..how difficult/expensive would it be to implement/allow for 2FA via hardware authenticators here be, if even possible  ?
It's possible. But I'd need to hear a pretty convincing argument for it before I'd spend my (limited) time working on that...

The thing is, I have an enormous amount of energy for certain things, and almost no energy whatsoever for other (sometimes even closely-related) things.

I've developed a pretty good sense over the years for how much of something (like TOTP, or U2F, or FIDO2, etc.) is based on good engineering and how much of it is based on profit-rationale. Things that were designed by engineering-types, without anything in mind except for the problem(s) being solved have a particular style/flavor to them that I really enjoy. Things that were designed or influenced by business-types, however, usually from a position of fear or greed, have a distinctly different style/flavor to them that I really don't enjoy. I have about a 10% tolerance I'd say: something needs to be at least 90% engineering-led for me to care enough about it to write code...

Honestly, I didn't do any kind of deep-dive on the available options when I decided to work on 2FA for the forum, I just started with the spec (TOTP) that seemed least likely to have been infected by business interests and went from there. It took me 20 minutes of reading (RFCs 6238 and 4226) to "see" the underlying design behind TOTP and to appreciate just how simple it is (that's normally a sign to me that what I'm looking at is/was an engineering-led initiative; business-types typically push for at least enough complexity to provide cover/justification for a revenue stream or two).

I've probably mentioned this in other posts, but it bears repeating: There's an unfortunate "word cloud" surrounding TOTP that makes it easy to misunderstand how it works, things like "Google Authenticator", and "QR code", etc. make it seem like maybe you need Google (you don't) or a phone (you don't) or a QR scanner/camera (you don't) or even an Internet connection (you don't) to use it. (For example, for my really important online accounts, I retrieve passwords and generate OTPs from an always-offline Linux laptop running an old version of KeePassXC.)

Fundamentally, TOTP is about you and the server having a so-called "shared secret" that can be used to algorithmically generate time-based OTPs. In Bitcointalk's case, that secret can be thought of as a system-generated number between 0 and 1329227995784915872903807060280344575 (inclusive). That number is presented to you in two ways on the account-settings page, as a Base32-encoded string, and as a QR code, but, at the end of the day, it's just a number. In principle, as long as you know what your number is, you can generate valid OTPs.

In fact, to drive home the point that TOTP is really simple, and has nothing (necessarily) to do with Google, phones, cameras, or the Internet, let's write a tiny, offline, standalone Python script and see if we can use that to enable 2FA on Bitcointalk and then successfully sign-in with it...

This post is already a wall, so I'll skip the step-by-step derivation and just share the script I arrived at:

Code: (genOTP.py)
#!/usr/bin/env python3

import time

import base64

import hmac

TOTP_SECRET: str = 'KBXXOZLSI5WG65TF'

TOTP_HASH_ALGORITHM: str = 'sha1'

TOTP_TIME_STEP: int = 30

TOTP_DIGIT_COUNT: int = 6

def main() -> None:

    now: int = int(time.time())

    secret: bytes = base64.b32decode(TOTP_SECRET)

    message: bytes = (now // TOTP_TIME_STEP).to_bytes(8, 'big')

    hashed: bytes = hmac.digest(secret, message, TOTP_HASH_ALGORITHM)

    offset: int = hashed[-1] & 15

    value: int = (hashed[offset] & 127) << 24 | hashed[offset + 1] << 16 | hashed[offset + 2] << 8 | hashed[offset + 3]

    result: str = str(value % 10 ** TOTP_DIGIT_COUNT).zfill(TOTP_DIGIT_COUNT)

    print(f'OTP: {result} [{TOTP_TIME_STEP - now % TOTP_TIME_STEP} second(s) left].')

if __name__ == '__main__':

    main()

So, now I'll go to my account-settings page and get my shared secret:



Then, I'll paste that into the above script (by replacing the placeholder secret on line 9):



We'll need to generate a valid OTP in order to enable 2FA, so let's see if our little script actually works:

Code:
python3 genOTP.py

OTP: 365017 [28 second(s) left].

Let's check the "Enable two-factor authentication?" box and type in the OTP we just generated:



Now let's (fairly quickly, before our OTP gets too old) type in our password and then click "Change profile":



And... 2FA is enabled:



Now, let's log out and make sure that we can log back in:



We'll need a valid OTP, so:

Code:
python3 genOTP.py

OTP: 820946 [23 second(s) left].

Okay, let's see if that works:



Click on "Login", and... Bob's your uncle. Cheesy



(To be clear, I'm not suggesting that you or anyone else use the above script, though of course you're more than welcome to, I just wanted to demonstrate that there's actually very little to TOTP, and that, if you had to, you could get by with just a small homebrew program and nothing else. I like TOTP because it's a nice, freedom-maximizing, simple algorithm that doesn't depend on anything in particular: it doesn't need OS-level support, it doesn't need browser-level support, it doesn't need special hardware or complicated/opaque/hidden software or drivers, etc.)



I wonder if implementing recovery codes would also be feasible (...)
Hey Rick. Sorry for taking so long to get back to you. I get what you're referring to, but, I don't know... I don't think recovery codes make that much sense for this implementation (in terms of value added vs. complexity added). There's already a worked-out mechanism for recovering access to your account if you lose your 2FA app/device (just do an e-mail based password reset and check the appropriate box). I guess, if people would really rather avoid doing a password reset, then, what they could do (though I don't recommend it, not unless they really know what they're doing) is keep a copy of their Base32-encoded secret somewhere, and then, if the need arises, they could either import that into something that easily accepts Base32 secrets, like KeePassXC, or they could paste/place it into the above script and (either way) then generate the OTPs necessary to get back into their account and disable 2FA (before presumably re-enabling it with a different/fresh shared secret).
legendary
Activity: 2282
Merit: 3014
PG- apologies if this has been covered.. 1) does turning on 2FA supersede the Security Question and disable it from being able to be deleted ?  2) jw ..how difficult/expensive would it be to implement/allow for 2FA via hardware authenticators here be, if even possible  ?

Cheers Smiley
legendary
Activity: 1148
Merit: 3117
That's what the "disable 2FA on a password reset" logic is for. The thinking there is that it's out-of-scope for the 2FA system to protect your account even in the face of your e-mail being compromised, so disabling 2FA on an e-mail based password reset is the "self-service" option to get back into your account if you've lost the ability to produce valid OTPs.
(...)
I wonder if implementing recovery codes would also be feasible (in the long term I suppose). The way this works on other websites/forums is that they are given to you whenever you activate 2FA and in the situation where you loose access to your 2FA device you can enter the recovery codes in order to regain control of your account. I do reckon, however, that these codes do act like a pointed spear on both ends - if helps you regain access to the account but also allows a malicious entity to gain control in case your computer gets compromised... The implementation on SMF doesn't seem to be that easy as well I suppose...
hero member
Activity: 510
Merit: 4005
Let me ask you to clarify one thing if you can,
What happens with saved 2FA that is activated in profile, when someone activates email change?
Do we have to create and activate new 2FA or not?
In terms of the code I sent theymos, there are no direct interactions between those settings (each can be changed without affecting the other), but two indirect interactions I can think of are:

(*) When 2FA is enabled, account settings (like your e-mail address) can't be changed without a valid confirmation OTP.

(*) If your set e-mail address is bogus (or otherwise inaccessible to you), and you lose the ability to produce valid OTPs (by, for example, your not-backed-up 2FA device getting damaged/stolen/lost), then you won't be able to receive the link that you need to disable 2FA as part of the password-reset process.
legendary
Activity: 2212
Merit: 7064
I'm thinking of suggesting to theymos that 2FA resets should show up as their own thing (distinct from password resets) in the security log. The way I see this working is that password resets will only show up as such if the password is actually changed. If you go through the password-reset process only to reset your 2FA (that is, by "changing" your password to what it currently is, and selecting the "Disable 2FA" option), then that'll show up in the seclog as "2FA reset via email" rather than "password reset via email" (and, obviously, if you do both of those things at the same time, that is, actually change your password and disable an enabled 2FA setting, then both events will show up in the seclog). Does anyone have any thoughts on this?
I think this is a good idea, but it will add more complexity and I am not sure theymos will continue to poke around it unless this is something that urgently needs to be updated.

Let me ask you to clarify one thing if you can,
What happens with saved 2FA that is activated in profile, when someone activates email change?
Do we have to create and activate new 2FA or not?
legendary
Activity: 1722
Merit: 4711
**In BTC since 2013**
And thanks to everyone else that left merit and/or left kind words (both here and in the "2FA added" thread). I appreciate it. Getting 2FA added to the forum seemed like a very steep climb when I initially took it on, but now that it's done, I don't really remember the pain, and it kind of feels like "Huh, that was actually pretty easy. What's next?". Cheesy

Now you can say that the "sky is the limit".  Cool

I think there should be very few modifications as complex as 2FA. Therefore, the next modifications will certainly be easier. We just hope this doesn't make you lose enthusiasm.
hero member
Activity: 510
Merit: 4005
Bitcointalk 2FA implementation looks so simple and clean, but I am sure it took you a lot of time to make everything work correctly.
Haha, yeah. It took a long time for things to settle into their final form. There were a few false starts at the beginning, and there was a good amount of trial-and-error and refining that took place throughout. From the vantage point of now having finished it, it's kind of underwhelming to look at the code (it's much more compact than you might imagine; the bulk of the code is in a file named TOTP.php and that file is about the same size LOC-wise as just the build script from FlappyCAPTCHA™).

One small thing I would suggest is adding recommendation to members to backup and shared secret key correctly, best with open source app like Aegis or similar.
Yup, that's a nice idea. But, security advice can sometimes backfire, and I'd hate to accidentally encourage people to write down their shared secret, or to screen-grab their QR code, or something similarly misguided. In some ways, it's actually better that people are caught a little by surprise that the shared secret disappears from view after 2FA has been enabled (I mean, savvy users won't find that practice surprising at all, and the set of people that do find it surprising likely overlaps with the set of people that would have tried to "save" their shared secret in a security-reducing way). Also, it's not like it's hard to reset your 2FA when needed (just do an e-mail based password reset and make sure the appropriate checkbox is ticked).



I'm thinking of suggesting to theymos that 2FA resets should show up as their own thing (distinct from password resets) in the security log. The way I see this working is that password resets will only show up as such if the password is actually changed. If you go through the password-reset process only to reset your 2FA (that is, by "changing" your password to what it currently is, and selecting the "Disable 2FA" option), then that'll show up in the seclog as "2FA reset via email" rather than "password reset via email" (and, obviously, if you do both of those things at the same time, that is, actually change your password and disable an enabled 2FA setting, then both events will show up in the seclog). Does anyone have any thoughts on this?



Hehe, thanks @EFS for the double merit-bomb. (I think that's my first one.) Wink

And thanks to everyone else that left merit and/or left kind words (both here and in the "2FA added" thread). I appreciate it. Getting 2FA added to the forum seemed like a very steep climb when I initially took it on, but now that it's done, I don't really remember the pain, and it kind of feels like "Huh, that was actually pretty easy. What's next?". Cheesy
legendary
Activity: 2212
Merit: 7064
Amazing work PowerGlove! This is one of the biggest positive changes in forum I have seen in last few years.
Bitcointalk 2FA implementation looks so simple and clean, but I am sure it took you a lot of time to make everything work correctly.
One small thing I would suggest is adding recommendation to members to backup and shared secret key correctly, best with open source app like Aegis or similar.
sr. member
Activity: 1666
Merit: 426
Congratulations @PowerGlove, pretty awesome feature, now you can work on the offensive security feature of 2FA because afaik, there are ways to bypass that authentication. From what I've heard, there was this one streamer that had his Steam account with a 2FA still being accessed by a third-party and at the same time ended with all of his in-game items stolen. I don't know though if it's a concern here though, just looking out.
legendary
Activity: 1708
Merit: 1280
Top Crypto Casino
I have just late seen this and I would like to congrats @PowerGlove for having this kind of feature now we can sleep well with having security and preventing accounts from getting compromised. Also for the future patch hope we can have the email or SMS (optional) so we can make another layer. Well by the way thank you!

Created a thread on our local with this feature: [Security] Additional Feature 2FA Implemented.
hero member
Activity: 510
Merit: 4005


(I've been sitting on that GIF for a while.) Cheesy

Congrats, PowerGlove.
Thanks, man. Grin
sr. member
Activity: 448
Merit: 688
In ₿ we trust
Very good! Any and all tools to provide more security are always welcome, congratulations on the excellent work!

Can you use physical 2FA too?
legendary
Activity: 2758
Merit: 6830
2FA added

Congrats, PowerGlove.

(And thank you. Cheesy)
legendary
Activity: 1722
Merit: 4711
**In BTC since 2013**
I was secretly hoping you might take over work or help with implementing of new forum software, (...)
I've been trying to convince theymos for some time to let me take over from Slickage and get things moving again. There's a lot of cool stuff I'd like to work on, but theymos and I each have our constraints, and reaching some kind of agreement that we're both happy with is tricky.

Perhaps for contractual reasons, they still can't do anything.

Honestly, I think you're trying to complicate something that could be very simple. SMF has new versions and continues to be forum software, well rated and widely used. Therefore, from my web developer experience, I think it would be more practical to maintain the software and update it, rather than changing everything. Of course, doing this does not invalidate the fact that it is necessary to carry out corrections to ensure that everything works as it does now. But, it is always easier to do this in more or less the same software, than to create everything from scratch.

Either way, I believe it was with good intentions that they thought about this change. Now, personally I continue to like how the forum works and is.  Smiley

legendary
Activity: 2212
Merit: 7064
In practice, you import your shared secret into some application that generates the OTPs for you (like one of the many authenticator apps, or password managers that support TOTP).
I can confirm this works with KeePassXC password manager, and few other apps I tried, but I wouldn't recommend saving 24-character secret in a plain text.

I've been trying to convince theymos for some time to let me take over from Slickage and get things moving again. There's a lot of cool stuff I'd like to work on, but theymos and I each have our constraints, and reaching some kind of agreement that we're both happy with is tricky.
Good to hear that you are trying and not giving up Wink
I can understand theymos partially, it is not easy to change something that you worked on for a very long time.
New forum software would mean more risk for new bugs, and than he would need to dedicate a lot more time for fixing this.
hero member
Activity: 510
Merit: 4005
I had one or two questions. How would one receive the OTP exactly? Is it via email or other 2FA apps?
The nice thing about the type of 2FA that this patch implements (TOTP) is that it's not based on "receiving" your OTP. What happens is that you "generate" your OTP (based on a shared secret and the current Unix timestamp), and then submit that to the server. In principle, as long as you know your shared secret (which, in this implementation, is just a 24-character string, like this: N4KMBX6DP5CUE6DCQ3BPOXN6), then you can generate valid OTPs. In practice, you import your shared secret into some application that generates the OTPs for you (like one of the many authenticator apps, or password managers that support TOTP).

I was secretly hoping you might take over work or help with implementing of new forum software, (...)
I've been trying to convince theymos for some time to let me take over from Slickage and get things moving again. There's a lot of cool stuff I'd like to work on, but theymos and I each have our constraints, and reaching some kind of agreement that we're both happy with is tricky.
copper member
Activity: 1330
Merit: 899
🖤😏
Since you are working on this forum, I guess there is no hope to see the new forum replacing this one any time soon, or are you working on the new one as well, I remember theymos once said he needs help of coders.
sr. member
Activity: 593
Merit: 271
I had one or two questions. How would one receive the OTP exactly? Is it via email or other 2FA apps? Normally, I don't use an email or number for my 2FA. Rather, I use Google Authenticator, or Authy, for my 2FA verification. So I was wondering, will there be support for apps like those? Previously, Google didn't support online backup of 2FA keys, but recently they upgraded it. However, I prefer Authy when it's about 2FA.

I hope this new patch gets theymos's approval.
copper member
Activity: 1526
Merit: 2890
The very first thought that popped in my head when I heard about recent Harizen hack was "I really hope that Powerglove's 2FA gets approved by theymos soon" so its great to hear that things are moving into the right direction and that we might finally get it, hopefully in a few months.

Regarding the bounty reward, it was set in BTC and not in $$ so who knows, maybe you get that 2 BTC (I surely hope you do  Grin).


Exactly those were my thoughts too... when I read Harizen's topic about account hack. Even I visited this thread and went to PowerGlove's profile to see if he have posted any update which I missed Smiley

I think what is stopping theymos from patching PowerGlove's this feature, is testing or lack of testing... since it's "closed source" patch and theymos himself have to verify and test before implementing.

If it was an open source patch it would have been implemented soon, because more eyes from the community to test are definitely better... and people can validate and verify faster before implementing.

P.S. I truly appreciate PowerGlove's skills so I'm not at all question his skills nor I'm saying he should share the patch. I can understand certain code can't be made public.
Pages:
Jump to: