function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jhartjhart 

Getting occasional false INVALID_LOGIN responses

Our application stores username & pwd/token credentials to execute API calls via the SOAP and WSDL apis.

For some customers, we see incorrect INVALID_LOGIN responses occasionally, and we'd like to understand why. 
This is a particular problem for us b/c, when we get an INVALID_LOGIN response, we assume the password has been changed and we pause integration. We also start sending "nag" emails to the customer to get them to give us the new pwd + token combo.

As you can imagine, our customers get very annoyed when they get this "nag" email but their username & password has not, in fact, changed.

Most recently this happened two days ago - on October 2nd at 12:29:12 pm (PDT), one of our API calls received this response:

INVALID_LOGIN: Invalid username, password, security token; or user locked out.

However, yesterday on the 4th (two days after this response), I verified that the username & password + token continued to work ... so the INVALID_LOGIN response was incorrect. (note that, because the token is unique for each new password, we can be certain that the password did not change - the same set of credentials worked before the 2nd, and after the 4th,  but that single "freak" response is enough to make our system think that the pwd is bad & to pause the integration.)


Please shed light on why we received that API response, and if this sort of behavior is expected with some percentage frequency. If so, we will need to change our algorithms to be on guard against false INVALID_LOGIN responses.

 

As far as we can tell it is somewhat rare, but does effect a small percentage (<1%) of customers at any given time; however it is quite disruptive for those it effects.

 

Salesforce support - we have opened case 08225908 to track this issue.

Best Answer chosen by Admin (Salesforce Developers) 
jhartjhart

Heard back from Salesforce support, and here's the answer to the puzzle.

 

The problem is that the customer has another integration component (in this case, Appirio), which is trying to login with a bad password.  After three attempts the entire user account is locked out (by default for 15 minutes).

 

During that lockout window, our application connects with valid credentials but is given an INVALID_LOGIN response because of the lockout.

 


I believe the real problem here is that Salesforce gives the exact same response to permanent login failures (bad password) as it does for transient, self-correcting ones (user lockout).

 

That puts 3rd party integration components in a bad spot, with two choice of behaviors:

 

a.  Considerate - when you get an INVALID_LOGIN response, assume it's a permanent error and stop trying to login in.  Notify the user that new credentials are needed.  This behavior has the pleasant characteristic of not locking out the user's account w/ repeated "bad password" login attempts.

 


b.  Selfish - when you get an INVALID_LOGIN response, assume it's a transient error and just keep trying.  If the user's account was merely locked out, this lets me eventually log back in without having to ask the user for a new password.  In the case of permanent error (eg, I have a bad password), this will have the nasty effect of locking out the user's account (and thus harming both the user and any other API clients that have the *right* password).

 

 

We chose (a) but are getting screwed by components that choose (b).  It's the prisoner's dilemma over here...  **bleep** for tat, anyone?  Random defector?  **bleep** for two tats?  Who's with me? (edit  - wow, I got bleeped out for a totally different use of the word.  I wonder what happens if I talk about a Tufted Titmouse?)

 

 

But really,  API clients should not be forced into this Sophie's choice at all.  Instead, salesforce should return different error codes for different errors.

 

In particular, "user locked out" should be its own response code so that applications can handle it with appropriate retry logic, which is totally different from the correct response for an actual bad password.

 

 

 

Edit: I"ve posted this request as an idea, although I should think that SFDC would see the merit in fixing this issue withou requiring a "get out the vote" campaign on my part....  That said, vote it up!

All Answers

Jia HuJia Hu
Have you checked if the Password has expired?
If this is the case, in the Profile, check 'Password Never Expires' and you can login again with API.
jhartjhart

Jia,

 

Perhaps my post wasn't clear enough.  If the password had expired, the user would have to reset their password, and then the security token would have changed.  But the exact same credentials worked both before and after the INVALID_LOGIN response; so password expiration is not the problem.

 

You're right that an expired password could cause this, and that the user could make that error go away if they turned off password expiration, which together would lead to a "good - INVALID_LOGIN - good" cycle with the same credentials, but (a) if that were the case, the user would not be annoyed, and would understand what occurred, and wouldn't be complaining to us, and (b) this happens _repeatedly_ with certain users.

 

jhartjhart

Heard back from Salesforce support, and here's the answer to the puzzle.

 

The problem is that the customer has another integration component (in this case, Appirio), which is trying to login with a bad password.  After three attempts the entire user account is locked out (by default for 15 minutes).

 

During that lockout window, our application connects with valid credentials but is given an INVALID_LOGIN response because of the lockout.

 


I believe the real problem here is that Salesforce gives the exact same response to permanent login failures (bad password) as it does for transient, self-correcting ones (user lockout).

 

That puts 3rd party integration components in a bad spot, with two choice of behaviors:

 

a.  Considerate - when you get an INVALID_LOGIN response, assume it's a permanent error and stop trying to login in.  Notify the user that new credentials are needed.  This behavior has the pleasant characteristic of not locking out the user's account w/ repeated "bad password" login attempts.

 


b.  Selfish - when you get an INVALID_LOGIN response, assume it's a transient error and just keep trying.  If the user's account was merely locked out, this lets me eventually log back in without having to ask the user for a new password.  In the case of permanent error (eg, I have a bad password), this will have the nasty effect of locking out the user's account (and thus harming both the user and any other API clients that have the *right* password).

 

 

We chose (a) but are getting screwed by components that choose (b).  It's the prisoner's dilemma over here...  **bleep** for tat, anyone?  Random defector?  **bleep** for two tats?  Who's with me? (edit  - wow, I got bleeped out for a totally different use of the word.  I wonder what happens if I talk about a Tufted Titmouse?)

 

 

But really,  API clients should not be forced into this Sophie's choice at all.  Instead, salesforce should return different error codes for different errors.

 

In particular, "user locked out" should be its own response code so that applications can handle it with appropriate retry logic, which is totally different from the correct response for an actual bad password.

 

 

 

Edit: I"ve posted this request as an idea, although I should think that SFDC would see the merit in fixing this issue withou requiring a "get out the vote" campaign on my part....  That said, vote it up!

This was selected as the best answer
jhartjhart

After escalating this within SFDC, their final response was "this is by design, there's a good reason for it, but we can't say what it is."

 

Which is the unmistakable telltale of a "it's for security" response.

 

Actually, as obtuse as their response was, upon reflection I do understand why they are doing it that way:

1. Salesforce wants to prevent username spearphishing

2. Therefore, a response for "valid username, invalid password" must be no different from the "invalid username" response

3. If the "locked out" response was any different from either response in (2), you could spearfish for usernames by trying the same username 3 times in rapid succession. If the response changed to "locked out", you would know that you have a valid username.

The fact that the R&D department won't openly say that is bizarre to me - disclosing this valid policy is no way makes it less effective, nor compromises security - but whatever.

 

 

Given what SFDC is trying to accomplish, and balancing that against the distributed pain of all API clients in handling this lockout issue, I would prefer to see their implemenation go the other way - return a different message on user lockout, so good actors can know what's going on, but implement the lockout logic for *all* usernames (including invalid ones) rather than just the valid ones.  I suppose this exposes them to a novel flavor of DOS attack, though...

SuperfellSuperfell

Have you considered OAuth? if you were storing a users refresh token instead of their credentials you wouldn't run into this issue (and would have to deal with passwords getting changed out from under you either). 

jhartjhart

Hi Simon,

 

Definitely OAuth is in our plans.  However, that doesn't help the hundreds of orgs who installed our package before OAuth was implemented by SFDC (or, more accurately, before we implement it too).

 

There's no way to create OAuth credentials as part of a push upgrade, is there?  Creating such credentials will always require user action, no?

 

thanks,

John