Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lpass login returns 'unknown' - iterations.php behavior changed #604

Open
mjbroekman opened this issue May 18, 2021 · 48 comments
Open

lpass login returns 'unknown' - iterations.php behavior changed #604

mjbroekman opened this issue May 18, 2021 · 48 comments

Comments

@mjbroekman
Copy link

mjbroekman commented May 18, 2021

Yesterday, I was using lastpass-cli (via Homebrew) fine, but this morning when I attempt to log in via lpass login <username>, I get the message "unknown" and prompted for the master password again.

$ lpass login username@email.com
Please enter the LastPass master password for username@email.com.

unknown
Master Password:

I am able to log in to both the browser extension and the website, so I know my credentials are correct. The only place I see 'unknown' that would be applicable to logging in is in the xml_error_cause function in xml.c, which gets called from endpoints-login.c

I also attempted to compile from the repo here and, following all the applicable steps for M1 and Homebrew, I get the same result.

Workaround

A workaround is to:

  1. Open Account Settings in your browser (Open My VaultAccount Settings)
  2. Press Show Advanced Settings
  3. Set General → Security → Password Iterations to exactly 100100

LastPass will ask for your Master password and re-encrypt your vault. After that using lpass should work again.

@rkirkpat
Copy link

I am getting the same error on a 2015 MacBookPro with MacOS 10.14 (Mojave), so it appears it is a lpass issue, or more likely the backend web APIs used by it.

@brendanlong
Copy link

Several people where I work are running into this on Ubuntu 20.04 as well.

@brendanlong
Copy link

I traced through the code and I think the problem is that iterations.php on the server is broken. The steps I see are:

  1. CLI does a request to lastpass.com/iterations.php with my username
  2. iterations.php returns 100100
  3. CLI does 100100 iterations of hashing
  4. CLI sends the result to lastpass.com/login.php with iterations=100100
  5. login.php returns an error saying iterations should be 5000

If I hack up cmd-login.c to hard-code iterations to 5000 I'm able to log in:

diff --git a/cmd-login.c b/cmd-login.c
index 27b2272..8e46232 100644
--- a/cmd-login.c
+++ b/cmd-login.c
@@ -96,6 +96,8 @@ int cmd_login(int argc, char **argv)
 
        username = argv[optind];
        iterations = lastpass_iterations(username);
+       printf("Server says %d iterations\n", iterations);
+       iterations = 5000;
        if (!iterations)
                die("Unable to fetch iteration count. Check your internet connection and be sure your username is valid.");

I'm not sure if this is the same for everyone, so to find this number you'll need to improve the error response handling:

diff --git a/xml.c b/xml.c
index 5961244..fecbde6 100644
--- a/xml.c
+++ b/xml.c
@@ -154,7 +154,9 @@ out:
        if (doc)
                xmlFreeDoc(doc);
        if (!result)
-               result = xstrdup("unknown");
+               xasprintf(&result, "unknown XML error: %s", buf);
+       if (!result)
+               result = xstrdup("unknown xml_error_cause");
 
        return result;
 }

@brendanlong
Copy link

Something weird is going on with iterations.php. If I click this link in my browser: https://lastpass.com/iterations.php?email=me@example.com it says 5000, but if I do curl https://lastpass.com/iterations.php?email=me@example.com it says 100100.

@mjbroekman
Copy link
Author

Something weird is going on with iterations.php. If I click this link in my browser: https://lastpass.com/iterations.php?email=me@example.com it says 5000, but if I do curl https://lastpass.com/iterations.php?email=me@example.com it says 100100.

I get the same results for my email and it's entirely (and poorly) UserAgent based. If I run curl and specify a UserAgent, I'm able to get back 5000 or 100100 depending on how 'valid' the user agent string is:

$ curl -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36' 'https://lastpass.com/iterations.php?email=me@example.com'        
5000                                                                                                                                                                                                   
$ curl -A 'Mozilla/5.0' 'https://lastpass.com/iterations.php?email=me@example.com' 
100100                                                                                                                                                                                                 
$ curl -A 'AppleWebKit/537.36' 'https://lastpass.com/iterations.php?email=me@example.com'
5000                                                                                                                                                                                                   
$ curl -A 'Chrome' 'https://lastpass.com/iterations.php?email=me@example.com'
100100                                                                                                                                                                                                 
$ curl -A 'Chrome/90' 'https://lastpass.com/iterations.php?email=me@example.com'
5000                                                                                                                                                                                                   
$ curl -A 'Safari' 'https://lastpass.com/iterations.php?email=me@example.com'
100100                                                                                                                                                                                                 
$ curl -A 'Safari/1' 'https://lastpass.com/iterations.php?email=me@example.com'
5000                                                                                                                                                                                                   
$ curl -A 'Safari/537.36' 'https://lastpass.com/iterations.php?email=me@example.com'
5000                                                                                                                                                                                                   
$ curl -A 'Firefox/537.36' 'https://lastpass.com/iterations.php?email=me@example.com'
5000                                                                                                                                                                                                   
$ curl -A 'Firefox/' 'https://lastpass.com/iterations.php?email=me@example.com' 
100100                                                                                                                                                                                                 
$ curl -A 'Firefox/88.0' 'https://lastpass.com/iterations.php?email=me@example.com'
5000

@brendanlong
Copy link

I'm trying to set the user agent in lpass but even if I send a Firefox user agent it's still not working there.

@brendanlong
Copy link

Ah I think this is the other fun part: lpass always uses HTTP POST but iterations.php only seems to work with GET requests now:

$ curl -A 'Chrome/90' https://lastpass.com/iterations.php?email=me@example.com
5000
$ curl -A 'Chrome/90' https://lastpass.com/iterations.php -d 'email=me@example.com'
100100
$ curl -A 'Chrome/90' https://lastpass.com/iterations.php -d 'email=me%40example.com'
100100
$ curl -A 'Chrome/90' https://lastpass.com/iterations.php?email=me@example.com -d ''
100100

@brendanlong
Copy link

Ah cool, so the user agent lpass uses is fine, it's entirely the GET issue. I think this is the fix:

diff --git a/endpoints.c b/endpoints.c
index 8f5b7d8..8ad5a5c 100644
--- a/endpoints.c
+++ b/endpoints.c
@@ -48,9 +48,11 @@ unsigned int lastpass_iterations(const char *username)
 {
        _cleanup_free_ char *reply = NULL;
        _cleanup_free_ char *user_lower = NULL;
+       _cleanup_free_ char *path = NULL;
 
        user_lower = xstrlower(username);
-       reply = http_post_lastpass("iterations.php", NULL, NULL, "email", user_lower, NULL);
+       xasprintf(&path, "iterations.php?email=%s", user_lower);
+       reply = http_post_lastpass(path, NULL, NULL, NULL);
 
        if (!reply)
                return 0;

(I have no idea if this introduces a memory leak or not 🤷 )

@mjbroekman
Copy link
Author

Hmm. With that code in place, lpass segfaults for me now.

@brendanlong
Copy link

brendanlong commented May 18, 2021

Well that's fun.. :\ I hardly ever write C so it's possible I'm doing something wrong here but I don't know what it is since it works for me.

@mjbroekman
Copy link
Author

Well that's fun.. :\ I hardly ever write C so it's possible I'm doing something wrong here but I don't know what it is since it works for me.

My guess is it's library related ... I'll keep poking at it on my end to see whether I can get it to work on my M1

@mjbroekman
Copy link
Author

I realized I had re-pulled the repo but not re-implemented the fixes for homebrew in #513 . After fixing CMakeLists.txt for Homebrew, it compiled and runs fine.

The elimination of POST in iterations.php is annoying though.

@rkirkpat
Copy link

I can confirm that the pull request above works for me on MacOS 10.14 (Mojave) on an MacBookPro 2015 using brew. I was able to do this as follows:

$ curl https://patch-diff.githubusercontent.com/raw/lastpass/lastpass-cli/pull/605.diff | shasum -a 256
14ced28cc06a335cd8ae850ff49841c08562391dfbe6b1ad4a585607778ebd04 -

$ brew edit lastpass-cli
Editing /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/lastpass-cli.rb
...insert after depends_on and uses_from...

  # Apply fix for iterations.php breakage.
  patch do
    url "https://patch-diff.githubusercontent.com/raw/lastpass/lastpass-cli/pull/605.diff"
    sha256 "14ced28cc06a335cd8ae850ff49841c08562391dfbe6b1ad4a585607778ebd04"
  end

$ brew reinstall -s lastpass-cli
==> Downloading https://patch-diff.githubusercontent.com/raw/lastpass/lastpass-cli/pull/605.diff
######################################################################## 100.0%
==> Downloading https://github.com/lastpass/lastpass-cli/releases/download/v1.3.3/lastpass-cli-1.3.3.tar.gz
Already downloaded: /Users/.../Library/Caches/Homebrew/downloads/5881a7a4f1a6bc8a050d7ae9afb718019425c89631ca153d699413e9773385c0--lastpass-cli-1.3.3.tar.gz
==> Reinstalling lastpass-cli
==> Patching
==> Applying 605.diff
patching file endpoints.c
patching file xml.c
==> cmake .. -DCMAKE_INSTALL_MANDIR:PATH=/usr/local/Cellar/lastpass-cli/1.3.3_1/share/man
==> make install install-doc
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/lastpass-cli/1.3.3_1: 11 files, 225.9KB, built in 9 seconds

$ lpass login me@example.com
Success: Logged in as me@example.com

Used https://www.ralfebert.de/snippets/brew-apply-patch-to-package-formula/ as a guide for the above. Thank you all for running this down and providing at a work-in-progress fix, I can at least use LastPass from the command line again!

@xdays
Copy link

xdays commented May 19, 2021

unknown XML error: <?xml version="1.0" encoding="UTF-8"?><response><error iterations="5000" /></response>

Got this error with patched version.

@woopstar
Copy link

I can confirm the steps for patching by @rkirkpat works for me too on MacBook Air (M1, 2020) using Big Sur 11.3.1 (20E241)

@detunized
Copy link

Hi everyone. I maintain a library that allows access to LastPass and other PMs. I noticed this issue as well. After some testing I see that the iterations.php endpoint is broken at the moment. Whatever it returns is not stable. Since it doesn't produce any error codes, it's hard to say if what it returned is a valid value or not. In the past, LastPass used to rely on the return value of login.php in order to resubmit with the correct iteration count again. This error looks like this: <response><error iterations="5000" /></response>. The value that is returned is the correct PBKDF2 iteration count. Why you see so much 5000s is that because this used to be the default values some years back. Now it's 100100. So it's normal to see that for older accounts where this setting has not been updated. Go set this value much higher, BTW.

In order to fix this issue, you'd need to login with the default value and parse the result and re-hash the password and re-login with the correct value returned from the server.

This is how I fixed in my library and it's tested and it works:
detunized/password-manager-access@bd2e31d

@woopstar
Copy link

@detunized

Go set this value much higher, BTW.

Where do you set this value?

@detunized
Copy link

@woopstar

Vault -> Account Settings -> General -> Show Advanced Settings -> Password Iterations

image

@mjbroekman
Copy link
Author

I can confirm that the patch submitted by @brendanlong continues to function properly even if you update the number of iterations to something other than 5000 or 100100.

@mattiasb
Copy link

@mjbroekman Could you remove "MacBook Air M1 - " from the title of this issue since it happens elsewhere as well? :)

@mjbroekman mjbroekman changed the title MacBook Air M1 - lpass login returns 'unknown' lpass login returns 'unknown' - iterations.php behavior changed May 19, 2021
@millerdrew
Copy link

I got this error as well with the patched version using the method from @rkirkpat (#604 (comment)):

unknown XML error: <?xml version="1.0" encoding="UTF-8"?><response><error iterations="5000" /></response>

But just changing my settings to a higher number like 200000 did not work. It only worked with changing my account settings to exactly 100100:
image

Thanks all for the help!

@mattiasb
Copy link

mattiasb commented May 19, 2021

I got this error as well with the patched version using the method from @rkirkpat (#604 (comment)):

unknown XML error: <?xml version="1.0" encoding="UTF-8"?><response><error iterations="5000" /></response>

But just changing my settings to a higher number like 200000 did not work. It only worked with changing my account settings to exactly 100100:
image

Thanks all for the help!

I had issues building the branch in #605 because of the issue in #532 . I rebased #605 over #532 (manually) and could build but the the patched lpass still gave the same issue for me so I gave up.

Now after reading the above comment by @millerdrew I just went into settings and changed Password Iterations to 100100 and now the regular¹ lpass without any of the above patches works fine.

@millerdrew could you test with your old unpatched lpass and see if that works for you? That would mean we have a rather solid non-intrusive workaround until this is fixed proper.

1: "regular lpass" here means whatever version of lpass that happens to be shipped with Fedora 33 on my laptop :P

@brendanlong
Copy link

Hm I'm not sure why even with my patch sometimes the iterations.php result is wrong. A better solution would probably be to call login.php and use the iterations it returns, then rehash and call it again. The code to do that was just more complicated than I was planning to write when my fix worked for me.

It looks like for most people the simplest workaround is to set your password iterations to 100100 though. I'll be doing that myself.

@brendanlong
Copy link

I updated my patch in #605 to use login.php to get the iteration count since hopefully that's more stable. I recommend that most people just update their password iterations to 100100 though (and probably a worthwhile security improvement on its own if yours is set to 5000).

@millerdrew
Copy link

@mattiasb I uninstalled lastpass-cli, and reinstalled without patching and I can confirm that it works now that my password iterations is set to 100100.

@mattiasb
Copy link

@mjbroekman could you append the following to your question (so that it's easily and immediately accessible to people coming here from the interwebs):

## Workaround

A workaround is to:
1. Open `Account Settings` in your browser (`Open My Vault``Account Settings`)
2. Press `Show Advanced Settings`
3. Set `General → Security → Password Iterations` to *exactly* `100100`

LastPass will ask for your Master password and re-encrypt your vault. After that using `lpass` *should*  work again.

@mattiasb
Copy link

@mjbroekman thanks! ❤️

@ghost
Copy link

ghost commented Aug 25, 2021

@brendanlong thank you for the fix! I applied the patch per @rkirkpat's splendid patching tips.

ansd added a commit to ansd/lastpass-go that referenced this issue Sep 19, 2021
Closes #44

As reported in lastpass/lastpass-cli#604,
on 18 May 2021 behaviour changed in LastPass servers.

Prior to that date, password iteration != 100100 was supported by this lib by first POSTing
to the /iterations.php endpoint to get the correct iterations count.

This commit fixes the broken /iterations.php behaviour as explained in
detunized/password-manager-access@bd2e31d#diff-708eab38b171b2961f6da413413fd63d1cff3d5fceda920289959678be35a184R51-R58:

"We no longer request the iteration count from the server in a separate request because it
started to fail in weird ways. It seems there's a special combination of the User Agent and cookies
that returns the correct result. And that is not 100% reliable. After two or three attempts
it starts to fail again with an incorrect result.

So we just went back a few years to the original way LastPass used to handle the iterations.
Namely, submit the default value and if it fails, the error would contain the correct value:
<response><error iterations="5000" /></response>"

So, we first try to login with the default 100100 iterations.
If it fails, we try to login again with the iterations from the error
message.
@slmingol
Copy link

@efx @brendanlong just trying to find out what the status of this issue is? Are we suppose to continue with the workaround 100100 or is there a proper fix coming down the pipe?

waterkip pushed a commit to waterkip/lastpass-cli that referenced this issue Nov 13, 2021
lastpass#604 (comment)

Signed-off-by: Wesley Schwengle <wesley@opperschaap.net>
@AndrewKassab
Copy link

@efx @brendanlong just trying to find out what the status of this issue is? Are we suppose to continue with the workaround 100100 or is there a proper fix coming down the pipe?

I am wondering the same. Have they dropped support for this?

@twilightsophie
Copy link

twilightsophie commented Feb 7, 2022

I have run into this problem today, I've only just found this thread so I'll be trying the workaround. My version of lastpass-cli according to brew upgrade lastpass-cli is 1.3.3.1 and I'm using a 2015 MacBook Pro with MacOS Catalina 10.15.7.

ETA: Changing the number to 100100 let me login.

@truthdoug truthdoug mentioned this issue Apr 12, 2022
@cjstaples
Copy link

Still an issue as of today. Thankfully, the workaround of updating password iterations to 100100 still succeeds.

@MartinPaulEve
Copy link

Still hitting this issue as of today -- the workaround still works but strangely the problem was intermittent (as in I wasn't getting this error until a few days ago and then it suddenly hit)

@mjbroekman
Copy link
Author

LastPass was having issues yesterday for a couple of hours during which it was impossible to access objects in your vaults.

sleepyfoxen pushed a commit to sleepyfoxen/lastpass-cli that referenced this issue Jan 9, 2023
- leaks data
- does not correctly return the number of pbkdf2 iterations on the vault
- use environment-sensitive

See: lastpass#604
@atipi
Copy link

atipi commented Jan 13, 2023

Hello, yesterday night I started to have the issue logging in to LastPass even my password is correct but using biometric in my iPhone is working fine.

By following conversation above, I don't see 'Password Iterations' option at all in LastPass UI in browser. What should I do?

@austinbutler
Copy link

Go to "Account Settings", click "Advanced", scroll down to the "Security" section, then look for "Password Iterations".

waterkip pushed a commit to waterkip/lastpass-cli that referenced this issue Jan 16, 2023
lastpass#604 (comment)

Signed-off-by: Wesley Schwengle <wesley@opperschaap.net>
@lukens
Copy link

lukens commented Feb 3, 2023

Has this been fixed yet? I hit this issue today, having recently updated my iterations to 2000000. Switching to 100100 got it working again.

@neirbowj
Copy link

neirbowj commented Apr 3, 2023

Is the LastPass CLI still considered a supported feature? In light of the fact that 100100 iterations is no longer considered sufficiently high, LastPass needs to resolve this issue one way or the other: enable CLI users to set iterations > 100100; or deprecate the CLI feature.

@0xdevalias
Copy link

0xdevalias commented Apr 26, 2023

Looks like May 1 2023 will be when this version of the CLI ceases to work correctly (unless they make required changes before then):

image

@lukens
Copy link

lukens commented Apr 26, 2023

@0xdevalias - where did you see this announcement? I've not seen it anywhere. I wonder if it's specific to your company's settings (assuming you're using a business edition/account).

@andrew-llh
Copy link

@lukens According to the Apr 28, 2023 LastPass Security Bulletin at https://support.lastpass.com/s/document-item?language=en_US&bundleId=lastpass&topicId=LastPass/security-bulletin-recommended-actions-free-premium-families.html&_LANG=enus:

Note: In the coming months, we will be increasing the minimum required iterations value for existing customers to 600,000 rounds. When this change takes place, all newly created accounts will begin with the new minimum default of 600,000 rounds, and all existing accounts will be upgraded automatically to meet the new minimum value (no customer action required).

mattiasb added a commit to mattiasb/.config that referenced this issue May 4, 2023
@0xdevalias
Copy link

@lukens That was in the LastPass desktop client, personal account, nothing to do with business/org accounts.

sleepyfoxen pushed a commit to sleepyfoxen/lastpass-cli that referenced this issue Aug 31, 2023
- leaks data
- does not correctly return the number of pbkdf2 iterations on the vault
- use environment-sensitive

See: lastpass#604
@neirbowj
Copy link

LastPass just notified me that it had changed the iterations on my "business user" account to 600,000. I confirmed in the advanced account settings area. I am still able to login and access secrets from the LastPass CLI (v1.3.7 on FreeBSD and on macOS via MacPorts).

$ curl -s "https://lastpass.com/iterations.php?email=$MYUSERNAME"
600000

Whew!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.