Skip to Content
0%

The API Security Myth That’s Putting Your Data at Risk

Computer, code hologram and man thinking of data analysis, night cybersecurity and software coding overlay. Programmer or person in glasses reading html script, programming or cybersecurity research.

Why source validation gives a false sense of security, and what actually protects your APIs.

In application security, context is everything. We frequently encounter high severity vulnerability reports, screaming “Critical CSRF” or “Session Hijacking,” but upon closer inspection, they reveal a misunderstanding of how APIs actually work. One of the most common misconceptions involves Origin Validation.

Using origin validation to authenticate the API traffic is like securing a building with a paperboard padlock. It looks secure from afar, but anyone with basic tools and knowledge can snap it in a heartbeat. Let us explore why this illusion is so prevalent and how the defence mechanism works. 

In a recent case study on our Messaging for In-App and Web (MIAW) SDK, the researcher demonstrated that a Python script could connect to a chat session and exchange messages, bypassing the official mobile banking app.  The researchers argued that the lack of validation of the Origin header resulted in this critical security failure. 

However, this finding was closed as “working as designed” as validating and replying on Origin headers gives a false sense of security for mobile APIs. The API assumes that possession of valid session credentials implies an authenticated client, regardless of the transport mechanism. In a zero trust architecture, the transport mechanism does not matter, the credentials do. 

To prove their point, researchers provided the following PoC:

The Scenario: The “Rogue” Python Script

The researcher provided a Proof of Concept (PoC) consisting of a Python script:

  1. Hardcoded a specific DEVICE_ID and Session Token.
  2. Send a request to the Salesforce messaging endpoint.
  3. Successfully initiated a chat session from a local machine (localhost) rather than the authorized banking website.

The researcher concluded that “The API fails to validate the request origin and an attacker can hijack the session.”

They suggested enforcing a check on the HTTP Origin or Referer header to ensure requests only come from https://example.com. While this sounds logical, it relies on a fundamental misunderstanding of Client Authority.

Why Origin Validation Fails for APIs

The above finding is a false positive based on the incorrect assumption of Client Authority. To understand why, we need to look at how security boundaries shift when moving from browser environment to script 

1. Browsers vs. Scripts

Engineers design the Origin header as a security feature for web browsers. When you visit a site, the browser automatically attaches this header to cross-site requests, helping servers decide whether to allow them (CORS). CORS is a security mechanism that prevents a malicious website from tricking your browser into making unwanted requests to a trusted domain (like your bank). It relies on the browser to check the “Origin” header and block unauthorized access.

However, an API talks to more than just browsers. It talks to mobile apps, servers, and, in the case of an attacker, scripts.

A Python script (or Curl, or Postman) acts as its own client. It controls every byte of the request. If we implement a rule stating “Only accept requests from https:/example.com,” the attacker simply updates their script:

Python

# The "Fix" Bypass

headers = {

    'Authorization': 'Bearer <stolen_token>',

    'Origin': 'https://bank.com',  # Spoofing the authorized domain

    'Referer': 'https://bank.com'

}

requests.post(api_url, headers=headers)

The server receives the correct header and allows the request. The attacker bypasses the security control with a single line of code.

2. The “Replay” Fallacy

The researcher’s PoC worked because they included a valid DEVICE_ID and Session Token in the script.

This highlights a critical distinction in security: Transport Security vs. Endpoint Compromise.

To execute this attack in the real world, the attacker first needs to acquire the Device ID and Session Token through some form of endpoint, application, or supply-chain compromise. Common vectors include:

  • Infecting the victim’s phone with malware.
  • Executing a Man-in-the-Middle (MITM) attack on the victim’s network.
  • Exploiting vulnerabilities in third-party libraries within the app.

If an attacker achieves this, they effectively own the user’s session. They hold the keys to the house. At that point, the API should honor the request because it carries valid credentials. Blocking the request based on network headers is like checking the ID of a person who is already inside your network. 

The Real Solution: Authenticated Messaging

If network headers cannot prove a request is legitimate, what can? Cryptography.

Instead of asking “Where does this request come from?” (which attackers can fake), ask “Who signed this request?”

For Salesforce MIAW and similar secure APIs, the gold standard is User Verification (Authenticated Messaging).

  1. The Handshake: When the user logs into your mobile app, your backend server generates a JSON Web Token (JWT).
  2. The Signature: Your system cryptographically signs this token using a private key that only you possess.
  3. The Verification: The app sends this signed JWT to Salesforce. We validate the signature against your public key.

Crucially, signed tokens must also be short-lived and scoped appropriately to limit replay risk. By enforcing strict expiration times (e.g., 5 minutes), you minimize the window an attacker has to use a stolen token, even if they manage to intercept it.

Defense in Depth

This approach exemplifies Defense in Depth. Even if the network layer is compromised (e.g., an attacker spoofs an IP or Origin header), and even if the client application is scrapped for generic API keys, the security holds. Why? Because, the requirement for a cryptographic signature acts as an additional layer that operates independently of the transport mechanism. By validating identity at the application layer, one ensures that access remains secure regardless of where the request originates.

If an attacker attempts to use a Python script, they may try to copy a DEVICE_ID, but they cannot generate a valid signed JWT for a new session without your private key. The API rejects the connection, not because the “Origin” looked wrong, but because the attacker failed to prove their Identity.

Key Takeaways for Developers

  • Do not confuse CSRF with API Replay: CSRF attacks trick a browser into doing something on a user’s behalf. API Replay attacks use stolen credentials in a custom, rogue client. They are completely different beasts requiring completely different defenses.
  • Origin headers are for constrained clients (browsers):  Browsers care about origin headers because they live in a constrained sandbox. Mobile APIs and server to server communications do not.
  • Identity over Geography:  Do not rely on the location of a request. Rely entirely on the cryptographic proof of who sent it.

At the end of the day, Security requires building walls that actually stop intruders, not just putting up “Keep Out” signs that attackers simply ignore. Security controls must meaningfully prevent unauthorized actions, not merely signal expected behavior to well-behaved clients.

For more information on securing your messaging sessions, check out the Salesforce guide on User Verification for Messaging for In-App and Web and the Developer Guide for User Verification APIs.

Security best practices

Curious about more ways to bolster the security of your Salesforce org? Check out our guide for additional guidance and resources.

Get the latest articles in your inbox.