Preface: OpenAI chose the Elixir ecosystem—specifically for its reference implementation of the Symphony agent orchestration framework—because agent orchestration is fundamentally a distributed systems problem, not a machine learning problem.
Background: Elixir has a robust ML ecosystem led by Nx (Numerical Elixir), Axon (deep learning framework), and Bumblebee (pre-trained Transformer models like GPT-2, Stable Diffusion, and Whisper). When developers deploy these models into production, they wrap them in a Phoenix web application. Because Bandit is the default HTTP server for Phoenix, it handles all the incoming HTTP requests containing user input (like prompts or images) and passes them to the underlying AI model for inference.
The Phoenix Framework is a highly scalable web development framework written in the Elixir programming language. Thanks to its core Erlang virtual machine (BEAM), it excels at handling millions of concurrent users simultaneously.
OpenAI uses the Elixir and Erlang ecosystem for agent orchestration projects like OpenAI Symphony, though the Phoenix web framework itself is more famously tied to specialized developer tools like Phoenix.new and AI platforms like Phoenix by Arize.
OpenAI relies on the underlying Elixir ecosystem for AI agent orchestration, and its open-source library, Symphony, integrates cleanly into the Phoenix runtime architecture.
But what is the reason Phoenix framework use Elixir HTTP server library?
The Phoenix Framework delegates the actual network plumbing to an underlying Elixir/Erlang HTTP server library (historically Cowboy and natively Bandit) to strictly enforce the separation of concerns.
Vulnerability details: The flaw is located in lib/bandit/websocket/connection[.]ex within the logic handling WebSocket continuation frame reassembly:
Left-Nested iolist and Repeated Traversal: When processing non-final continuation frames, the length validation check oversize_message?/2 appends new frames into a left-nested iolist. It then invokes IO[.]iodata_length/1 to measure the total size of the accumulated buffer every time a new frame arrives.
Quadratic Complexity (O(n²)): Because the buffer size grows linearly with each frame and the entire structure is re-traversed from scratch upon each addition, the algorithm’s time complexity spikes quadratically to O(n²).
Bypassing Length Limits: Although the default max_fragmented_message_size caps the total message size (default 8 MB), it does not limit the number of individual frames. Each malicious frame can carry a payload as small as 1 byte.
Official announcement: Please refer to the link for details –