Misconfiguration Abuse in Apex Callout Proxy

This lab explains how a generic Apex HTTP relay endpoint can become an attacker-controlled proxy, enabling unauthorized outbound calls, token/header leakage, and SSRF-like abuse from trusted Salesforce infrastructure.

Executive Summary

Developers often create reusable callout helpers that accept runtime URL, method, headers, and payload. This pattern is dangerous when exposed to UI/API clients without strict action allowlisting and authorization controls.

In managed packages, a relay-style proxy can break trust boundaries by allowing untrusted users to send requests to unintended destinations with package credentials.

Salesforce Attack Surface

  • Generic relay endpoints: methods accepting arbitrary URL, method, body, and headers
  • User-influenced callout targets: host/path supplied from client-side parameters
  • Header passthrough: forwarding auth headers or package secrets to attacker-controlled domains
  • Protocol and route abuse: hidden internal endpoints reachable through relay behavior
  • Weak authorization: low-privilege users invoking proxy functions intended for admin integrations

Business Impact

  • Unauthorized outbound access: package abused as a request-forwarding tunnel
  • Data exfiltration: sensitive payloads and headers sent to attacker infrastructure
  • Credential compromise: API tokens leaked through outbound relay misuse
  • Incident response blind spots: malicious traffic appears as trusted package callouts
  • Security review blockers: AppExchange findings for unrestricted endpoint and method control

PoC Use Cases

@AuraEnabled
public static String relay(String endpoint, String method, String body, Map<String, String> headers) {
    HttpRequest req = new HttpRequest();
    req.setEndpoint(endpoint); // User-controlled destination
    req.setMethod(method);     // User-controlled HTTP verb
    for (String name : headers.keySet()) {
        req.setHeader(name, headers.get(name)); // Header passthrough
    }
    req.setBody(body);
    HttpResponse res = new Http().send(req);
    return res.getBody();
}
  • Attacker points relay to a controlled endpoint and captures package-originated traffic.
  • Sensitive headers are forwarded from platform-side request context.
  • Relay path is used as an unauthorized outbound proxy channel.

Testing Methodology

  • Relay endpoint inventory: identify every Apex method exposing dynamic callout control
  • Input influence mapping: trace which parameters affect host, path, headers, and method
  • Authorization tests: verify low-privilege users cannot trigger relay behavior
  • Leak validation: confirm whether secrets/headers are forwarded to untrusted targets
  • Exploit evidence: collect request/response traces proving proxy abuse and impact

Secure Engineering Patterns

  • Action allowlists: map business actions to fixed Named Credential endpoints
  • No raw URL input: block arbitrary destination, method, and header control
  • Server-side authZ: enforce explicit permission checks before outbound operations
  • Safe header policy: only set approved headers, never pass client-supplied auth headers
  • Observable controls: alert on unusual host/action combinations and relay misuse attempts
private static final Map<String, String> ACTION_TO_ENDPOINT = new Map<String, String>{
    'syncProfile' => 'callout:Partner_API/profile/sync',
    'createCase'  => 'callout:Partner_API/case/create'
};

@AuraEnabled
public static String relaySafe(String actionKey, String payload) {
    if (!ACTION_TO_ENDPOINT.containsKey(actionKey)) {
        throw new SecurityException('Action not allowed');
    }
    if (!FeatureManagement.checkPermission('PKG_Integration_Execute')) {
        throw new SecurityException('Not authorized');
    }

    HttpRequest req = new HttpRequest();
    req.setEndpoint(ACTION_TO_ENDPOINT.get(actionKey));
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setBody(payload);
    return new Http().send(req).getBody();
}

Verification Checklist

  • No endpoint accepts user-supplied arbitrary destination URLs
  • HTTP methods and headers are fixed by server-side policy, not client input
  • Outbound actions are permission-gated and logged for abuse detection
  • Named Credentials are used for endpoint/auth governance
  • Security tests validate relay misuse and exfiltration scenarios are blocked

Lab Exercises

  • Exercise 1: Identify and map all dynamic relay parameters in vulnerable Apex code
  • Exercise 2: Demonstrate unauthorized outbound request forwarding with controlled host
  • Exercise 3: Prove sensitive header leakage through passthrough relay behavior
  • Exercise 4: Refactor to action-based allowlist with Named Credentials and auth checks
  • Exercise 5: Re-test and package evidence for AppExchange security review