My phone died a few days ago, and the Cisco Duo app overwrote 2FA key backup after connecting my old phone to the internet.
Lemmy has no backup codes, nor can you disable 2FA even while logged in without a valid token.

Anyway, I noticed there’s no rate limiting on 2FA attempts.
So following Lemmy API docs I wrote this exceptionally stupid script (look at my foolish way of parallelization and no auto-stop).

I got the JWT token from logged-in Firefox session, using cookies.txt extension to export it.

Anyway, just make sure your password is secure enough, It’s obviously (potentially) better than 6 digits, probably with 3 valid combinations at each time (current 30s, past 30s, future 30s windows), if I am guessing how it works right.

My attempt also clearly involved a lot of luck with just 21,830 attempts (less than 5 minutes). But, if you’re lucky enough, you may guess it on first attempt, or never if you aren’t.

  • Darkassassin07@lemmy.ca
    link
    fedilink
    English
    arrow-up
    115
    ·
    6 days ago

    Anyway, I noticed there’s no rate limiting on 2FA attempts.

    Well that’s mildly horrifying… May as well not even have 2fa. Especially with no failed auth attempt notifications (well, no notifications at all really; I hate this part of lemmy)

    Glad I don’t have/keep anything private here.

    • bamboo@lemmy.blahaj.zone
      link
      fedilink
      English
      arrow-up
      39
      arrow-down
      1
      ·
      6 days ago

      Not do downplay this issue, but based on the description, OP had a valid session cookie, and was updating their profile to disable MFA since they lost the code. They weren’t brute forcing logging in.

      I haven’t looked into the source code, maybe this is an instance by instance configuration, but login attempts are rate limited. After a few failed attempts, I started getting this message:

      Lemmy Error: You’re being rate limited, wait a bit before trying that again.

      • u/lukmly013 💾 (lemmy.sdf.org)@lemmy.sdf.orgOP
        link
        fedilink
        English
        arrow-up
        26
        ·
        6 days ago

        I just did a manual test with sh.itjust.works comparing it to lemmy.blahaj.zone.

        sh.itjust.works keeps accepting attempts
        lemmy.blahaj.zone blocks after I think 3 attempts (I forgot to pay attention)
        lemmy.ml also blocks after 3 attempts

        sh.itjust.works and lemmy.blahaj.zone even use the same version, lemmy.ml is on a 0.19.6 beta.

        Going further, lemmy.world: no blocking (as far as tested)
        lemm.ee: no blocking (as far as tested)
        sopuli.xyz: after 10 attempts

        Summary: SDF is using old version, the rate limiting seems to be variable suggesting a setting

        Analysis: lemmy.ml, lemmy.blahaj.zone and sopuli.xyz appear to be exposed directly (.zone doesn’t respond without SNI, other 2 show NGINX page). NGINX can pass client IPs in headers. The rate limiting appears to be IP-based.
        sh.itjust.works, lemmy.world and lemm.ee are all behind CloudFlare.

        Hypothesis: Either a problem with passing client IP headers from cloudflared or the instance admins simply trust CloudFlare to provide some rate limiting.

        • Darkassassin07@lemmy.ca
          link
          fedilink
          English
          arrow-up
          4
          ·
          edit-2
          6 days ago

          a problem with passing client IP headers from cloudflared

          I’d be willing to bet this is it. My nginx proxy needs special config to pass client IPs correctly to backend services. Otherwise the backend just sees the IP of the proxying cloudflare server.

          proxy_set_header X-Real-IP $http_cf_connecting_ip;

          A cloudflare specific header. The typical $remote_addr I use elsewhere has the cloudflare server’s IP when cloudflared is involved.

    • Draconic NEO@lemmy.dbzer0.com
      link
      fedilink
      arrow-up
      1
      ·
      4 days ago

      2FA in lemmy is a gimmick more than anything else, it’s more trouble than it is worth and comes with a significant risk of losing your account. It is better than it used to be but I still wouldn’t consider it good. Best to just not use it.

  • ashitaka@lemmy.world
    link
    fedilink
    arrow-up
    35
    ·
    6 days ago

    If it’s stupid and it works, it’s not stupid.

    Good job on tackling this problem in a creative way.

    • Lung@lemmy.world
      link
      fedilink
      arrow-up
      5
      ·
      6 days ago

      I think I would have given up before reading the documentation & analyzing the code to notice lack of rate limit. Now I’m questioning if 2fa was ever secure with such a limited brute force space

  • Gormadt@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    30
    ·
    6 days ago

    Not rate limited‽

    Holy shit that’s one hell of a security oversight

    Hell just making it so after 3 failed attempts it can’t be retried for an hour would have made your efforts take over 7000 hours rather than 5 minutes.

  • Draconic NEO@lemmy.dbzer0.com
    link
    fedilink
    arrow-up
    21
    ·
    6 days ago

    I’m really not a fan of 2FA since if I lose or break my phone in most 2FA implementations you just get locked out. Nothing to do. Even with TOTP keys it’s just an extra password I have to remember. I don’t want to do that, the marginal increase doesn’t feel worth the risk of being locked out of my account.

    So I just won’t use 2FA, especially on Lemmy of all places. Oh how I’ve heard the horror stories of people using the early 2FA implementation and getting locked out. Not me, not ever, people may say it’s better these days but this still doesn’t seem worth it.

    • nimpnin@sopuli.xyz
      link
      fedilink
      arrow-up
      13
      ·
      6 days ago

      What’s the point of using 2FA on non-crucial accounts anyway? If somebody wants to hack my lemmy account or something, I don’t really care at the end of the day.

      • Draconic NEO@lemmy.dbzer0.com
        link
        fedilink
        arrow-up
        5
        ·
        6 days ago

        There really isn’t any need, it’s very much overkill. I’d say in the vast majority of places where it is asked it is not needed and can even be a bad thing due to the risk of losing account access.

    • slampisko@lemmy.world
      link
      fedilink
      arrow-up
      6
      ·
      6 days ago

      I’m using Aegis Authenticator and I regularly back up my list to an external file uploaded to my NAS. If my phone dies (which has happened before), I can then just restore the list from the backup ¯\_(ツ)_/¯

    • Lung@lemmy.world
      link
      fedilink
      arrow-up
      4
      arrow-down
      5
      ·
      6 days ago

      Yeah! Defeat the dragon of phone 2fa by putting all your secondary passwords on the cloud, synced to your computer! That’ll show em :D

        • needanke
          link
          fedilink
          arrow-up
          1
          ·
          5 days ago

          If you sync it it isn’t offline by definition. Might not have to be on google/one drive, but has to be acessible over some network (probably even the internet).

          • Trainguyrom@reddthat.com
            link
            fedilink
            English
            arrow-up
            2
            ·
            5 days ago

            Syncing can be through a peer to peer protocol such as sync thing where both devices would need to know each other’s Device IDs, and the Device IDs are basically just SHA256 hashes of locally generated keys.

            Or if the user uses a program to sync over the local network or over USB it’s not necessarily online

          • itslilith@lemmy.blahaj.zone
            link
            fedilink
            arrow-up
            1
            ·
            5 days ago

            You mentioned cloud, and that’s really not needed. If you need sync, you can use a P2P service like Syncthing, and while your data is transmitted over the Internet, any threat actor would need to

            a) identify your device IDs and intercept your traffic b) crack the encryption of the network traffic c) crack your password d) (if you used a key file, crack that as well)

            If that is not safe enough for your threat profile, sure, don’t use a password manager, but at that point you got bigger problems

  • assaultpotato@sh.itjust.works
    link
    fedilink
    arrow-up
    8
    ·
    6 days ago

    If the average case is 20 minutes and you saved 21 minutes doing a less good solution that still worked, you made the right choice.

  • bl_r@lemmy.dbzer0.com
    link
    fedilink
    arrow-up
    5
    ·
    6 days ago

    Hell yeah

    This is like the time I forgot the password to my LUKS drive and started brute forcing it using john and a custom password generation function.

    I didn’t get nearly as lucky as you, it took around 18 hours, but I got in. Which was lucky since that luks drive had the sole 512 byte key to my long-term storage drive that had important paperwork on it.

    • needanke
      link
      fedilink
      arrow-up
      1
      ·
      5 days ago

      Did you still remember lots of your password parameters, or was it just really short to be solved that fast?

      • bl_r@lemmy.dbzer0.com
        link
        fedilink
        arrow-up
        3
        ·
        5 days ago

        I remembered about 60% and I knew the general format of the password. It was about 30-40 characters in length so it was far from short. I couldn’t remember one of the words, the numbers, or the symbols, nor could I remember the order of the numbers and symbols since I diverted from the pattern I used to use due to the significance of the password.

        I made a custom dictionary, and used john with a custom generator to make it fit the possible format of my password so that is why it was so fast. Had I not done that, it probably would have been feasible. It was also an older less secure luks partition so that helped a ton, and the fact I had a mediocre gpu (2070max-q) was the icing on the cake.

        I intentionally keep no copies of my encrypted drive passwords so I was fucked if I couldn’t remember the password.