Best Practices for Salesforce API Integrations: Stop Using Username-Password Flow

How to avoid security risks introduced by particular OAuth Flows
External apps and inbound integrations need to authenticate with Salesforce to exchange data. There are different types of authentication possibilities. Do you know which ones are used in your Orgs?
One common, yet highly problematic method, is the Username-Password OAuth flow for Salesforce API integrations. This flow poses severe security risks and is strongly discouraged. Salesforce offers more secure alternatives like the OAuth 2.0 Web Server flow with Proof Key for Code Exchange (PKCE) and the OAuth 2.0 client credentials flow.
The Username-Password flow has historically been used for its simplicity, but in today's threat landscape, it is woefully insecure
This post explains the significant problems with this OAuth flow and provides guidance on how to avoid these risks.
Is the Username-Password Flow Enabled in Your Org?
Salesforce blocks the Username-Password flow by default for Orgs created with the Summer '23 release or later. However, if your org is older, you must check if any apps are using this flow and disable it immediately if no longer needed.
How to Check If Username-Password Flow Is Enabled:
- Go to Setup > OAuth and OpenID Connect Settings > OAuth and OpenID Connect Flows.
- If the setting is "On", plan to disable it. This involves ensuring no critical integrations rely on this flow. Migrate any such integrations to a more secure flow like OAuth 2.0 Web Server flow with PKCE or OAuth 2.0 Client Credentials flow.
Important Note: Even if this setting is "Off", the SOAP Login operation and Cross-org Connectors still allow potential attackers to use username-password logins. This means password-authenticated access via APIs remains a risk.
How to Detect Username-Password Logins
- Regularly review the Login History. Look for logins with the login type "Remote Access 2.0" and subtype "OAuth Username-Password."
- Examine the user, connected app name, IP address, and country for suspicious activity (e.g., unfamiliar app names, unusual locations, times of day, or error messages).
- Be aware: SOAP and Cross-Org connector logins appear as "Other Apex API" without a subtype and with the useless application name "N/A." This makes it difficult to definitively detect password-based authentication for these methods. "Other Apex API" logins may indicate password-based authentication.
- Action: If suspicious logins are detected:
- Change the user's password to invalidate it and the associated security token.
- Disable Username-Password flows (but be aware this may disrupt legitimate uses).
Key Security Risks of Username-Password Flow
The Username-Password flow is insecure for several critical reasons:
- Full Compromise Risk: Stealing a username-password pair with the security token allows an attacker to impersonate the user and perform any authorized action, leading to a full compromise. In contrast, a stolen OAuth refresh token only grants access to Salesforce APIs within defined scopes.
- Integration Breakage: Changing the user's password or security token without updating the integration breaks the connection and floods the Login History with "Failed login" errors.
- Password Exposure: Passwords sent in query parameters (or even in the POST body) may be logged, potentially exposing credentials. Sending unencrypted passwords over the wire is inherently risky.
- Lack of Refresh Tokens: The absence of refresh tokens means the integration is not visible in the OAuth token list and cannot be easily revoked.
Security Token: A False Sense of Security?
The Username-Password flow requires a "security token" (a Salesforce-generated second password) in addition to the user's password. While this improves security and might seem like multi-factor authentication, it is not a true replacement for MFA. The security token is appended to the password (e.g. `mypasswordXXXXXXXXXX`).
If an attacker obtains the "password + security token" string, they can bypass this control. This can happen if:
- The pair is logged and the attacker gains access to the logs.
- The pair is stored in a service like Postman and the attacker gains access to that account.
- The pair is hardcoded in source code that is accidentally exposed (e.g., on a public GitHub repository).
While older Salesforce orgs may have allowed username-password logins without a security token, it is now generally required in newer orgs.
Critical Mitigation Steps If Username-Password Flow Is Unavoidable
If you absolutely must continue using the Username-Password flow due to legacy integrations or third-party app limitations, understand that you remain at risk. However, you can take the following steps to minimize that risk:
- Dedicated Integration User: Create a dedicated integration user with the absolute minimum necessary permissions.
- Disable interactive logins for this user.
- Generate a very strong, long password and store it securely in a secrets manager.
- Secrets Scanning: Regularly scan all source code repositories and local drives using tools like GitGuardian or TruffleHog to detect any accidentally exposed passwords or security tokens. While these tools may have limitations with Salesforce usernames and passwords as they contain no magic token strings, they can still catch many common issues.
- Login History Monitoring: Diligently monitor the Salesforce Login History for any unusual activity related to the Username-Password flow (subtype "OAuth Username-Password").
- Regular Rotation: Regularly rotate the password and security token for the integration user. This means updating both Salesforce and the configuration of the external integration.
- Lock down connected apps: Use the combination of Transactional Security Policies and OAuth policies to lock down allowed apps and to limit the risk of attackers using a connected app to log in to the Org.
Important Note on Salesforce OAuth Policies
Salesforce OAuth policies for connected apps (IP restrictions, admin approval) only apply to admin-created connected apps. An attacker with the "password + security token" combo can create their own Connected App in a Trailhead org and bypass these restrictions. Or, they can just use a Cross-org Connector or SOAP. Hence, the use of these policies doesn’t prevent attackers from using stolen credentials to log in through the APIs. |
How can Valo help?
Valo offers features to detect and mitigate risks from the Username-Password flow:
- Warns about the usage of the Username-Password flow.
- Detects anomalous connections and API usage from integrations.
- Provides an AI agent to assist with investigating issues and changing configurations.
- Helps build minimized permission sets for integration users.
If you find this blog information useful, we welcome you to share it with your teams and in your LinkedIn and Salesforce relevant groups.
About Mika
Mika Ståhlberg is the CTO and Co-founder of Valo, bringing 25 years of experience in cybersecurity and R&D to the role. Previously, Mika led security initiatives at Ouraring and served as CTO at F-Secure. He is a Salesforce Certified Integration Architect with extensive experience in leadership and hands-on technology work. Mika is passionate about building usable products that effectively solve customer problems.
Outside of work, Mika enjoys snowboarding, music, and exploring history.
Mika Stahlberg