Open mjbroekman opened 3 years ago
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.
Several people where I work are running into this on Ubuntu 20.04 as well.
I traced through the code and I think the problem is that iterations.php on the server is broken. The steps I see are:
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;
}
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.
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
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.
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
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 :shrug: )
Hmm. With that code in place, lpass segfaults for me now.
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.
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
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.
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!
unknown XML error: <?xml version="1.0" encoding="UTF-8"?><response><error iterations="5000" /></response>
Got this error with patched version.
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)
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: https://github.com/detunized/password-manager-access/commit/bd2e31d3478309a2d9a5e171b0422a1a254c3a57
@detunized
Go set this value much higher, BTW.
Where do you set this value?
@woopstar
Vault -> Account Settings -> General -> Show Advanced Settings -> Password Iterations
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.
@mjbroekman Could you remove "MacBook Air M1 - " from the title of this issue since it happens elsewhere as well? :)
I got this error as well with the patched version using the method from @rkirkpat (https://github.com/lastpass/lastpass-cli/issues/604#issuecomment-843612877):
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:
Thanks all for the help!
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:
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
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.
I updated my patch in https://github.com/lastpass/lastpass-cli/pull/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).
@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.
@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.
@mjbroekman thanks! ❤️
@mjbroekman thanks! ❤️
Thanks for pointing out the workaround.
I've had the same issue. Setting "Password Iterations" to 100100 also fixed it for me.
But I wanted to add something else to this bug description. I have the following script in my .zshrc:
alias lp='lpass show -c --password $(lpass ls | fzf | awk '"'"'{print $(NF)}'"'"' | sed '"'"'s/\]//g'"'"')'
If I run "lpass login" I was unable to login. If I run "lp" I would be prompted for a login and I would be successfully authenticated. So there must be some different mechanism between "lpass login" and "lpass show" where the second one doesn't have this iterations issue.
I've had the same issue. Setting "Password Iterations" to 100100 also fixed it for me.
But I wanted to add something else to this bug description. I have the following script in my .zshrc:
alias lp='lpass show -c --password $(lpass ls | fzf | awk '"'"'{print $(NF)}'"'"' | sed '"'"'s/\]//g'"'"')'
If I run "lpass login" I was unable to login. If I run "lp" I would be prompted for a login and I would be successfully authenticated. So there must be some different mechanism between "lpass login" and "lpass show" where the second one doesn't have this iterations issue.
The only thing I can think of is that lpass show
or lpass ls
are hitting a different endpoint that grabs the 'correct' number of iterations for you to be able to login with a different number of iterations. Hopefully the devs will be able to information in this thread to fix it in a way that allows non-default iterations to work properly.
@strider4560, @mjbroekman It is likely that they save the iteration count with the blob and don't need it when refetch. Or they don't refetch at all and the password is only used to decrypt the already downloaded blob.
@detunized I think you're right. I logged in with lpass, killed my agent, changed my iterations count, and now "lp" can't log me back in. So it sounds like the iterations wasn't being refetched with "lpass show".
@brendanlong thank you for the fix! I applied the patch per @rkirkpat's splendid patching tips.
@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?
@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?
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.
Still an issue as of today. Thankfully, the workaround of updating password iterations to 100100 still succeeds.
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)
LastPass was having issues yesterday for a couple of hours during which it was impossible to access objects in your vaults.
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?
Go to "Account Settings", click "Advanced", scroll down to the "Security" section, then look for "Password Iterations".
Has this been fixed yet? I hit this issue today, having recently updated my iterations to 2000000. Switching to 100100 got it working again.
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.
Looks like May 1 2023 will be when this version of the CLI ceases to work correctly (unless they make required changes before then):
@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).
@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).
@lukens That was in the LastPass desktop client, personal account, nothing to do with business/org accounts.
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!
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.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:
Account Settings
in your browser (Open My Vault
→Account Settings
)Show Advanced Settings
General → Security → Password Iterations
to exactly100100
LastPass will ask for your Master password and re-encrypt your vault. After that using
lpass
should work again.