CVE-2026-8467 Overview
CVE-2026-8467 is a critical code injection vulnerability [CWE-94] in the phenixdigital/phoenix_storybook library for Elixir/Phoenix applications. The flaw allows unauthenticated attackers to achieve remote code execution through unsanitized attribute value interpolation in HEEx template generation. The psb-assign WebSocket event handler accepts arbitrary attribute names and values from clients without authentication, and these values are interpolated into a HEEx template that is compiled and executed server-side. Affected versions span phoenix_storybook 0.5.0 up to but not including 1.1.0.
Critical Impact
Unauthenticated network attackers can execute arbitrary Elixir code on the server with full Kernel imports and no sandbox, leading to complete system compromise.
Affected Products
- phenixdigital/phoenix_storybook versions 0.5.0 through 1.0.x
- Phoenix applications mounting the storybook playground in development or production
- Elixir/Erlang services exposing the PlaygroundPreviewLive LiveView endpoint
Discovery Timeline
- 2026-05-20 - CVE-2026-8467 published to NVD
- 2026-05-20 - Last updated in NVD database
Technical Details for CVE-2026-8467
Vulnerability Analysis
The vulnerability resides in the playground rendering pipeline of phoenix_storybook. The psb-assign WebSocket event handler in Elixir.PhoenixStorybook.Story.PlaygroundPreviewLive.handle_event/3 accepts arbitrary attribute names and values from unauthenticated clients. These values are forwarded to Elixir.PhoenixStorybook.Helpers.ExtraAssignsHelpers.handle_set_variation_assign/3, which stores them verbatim without validation or escaping.
When the component is later rendered, Elixir.PhoenixStorybook.Rendering.ComponentRenderer.attributes_markup/1 interpolates binary attribute values directly into a HEEx template string in the form name="<val>". No escaping is applied to double quotes or to HEEx expression delimiters such as {...}. The resulting template is compiled via EEx.compile_string/2 and executed via Code.eval_quoted_with_env/3 with full Kernel imports and no sandbox.
Root Cause
The root cause is unsafe string concatenation when generating HEEx markup. Attacker-controlled binary values are trusted as static template fragments rather than being treated as runtime data. Because HEEx attribute interpolation ({expr}) is evaluated as inline Elixir, any injected expression delimiters break out of the attribute context and into the code-evaluation context.
Attack Vector
An attacker connects to the storybook LiveView WebSocket endpoint and sends a psb-assign event containing an attribute value such as foo" injected={EXPR} bar=". The closing quote terminates the original attribute, and {EXPR} is parsed as an inline Elixir expression. When EEx.compile_string/2 and Code.eval_quoted_with_env/3 process the template, EXPR executes on the server with full standard library access, enabling arbitrary command execution, file access, and lateral movement.
# Patch excerpt from .credo.exs in commit 56ab8464
{Credo.Check.Warning.IoInspect, []},
{Credo.Check.Warning.OperationOnSameValues, []},
{Credo.Check.Warning.OperationWithConstantResult, []},
- {Credo.Check.Warning.RaiseInsideRescue, []},
{Credo.Check.Warning.SpecWithStruct, []},
{Credo.Check.Warning.WrongTestFileExtension, []},
{Credo.Check.Warning.UnusedEnumOperation, []},
Source: GitHub Commit 56ab8464 - the broader commit replaces unsafe HEEx attribute generation with a safe rendering path.
Detection Methods for CVE-2026-8467
Indicators of Compromise
- Unexpected psb-assign WebSocket events containing double-quote characters or { / } sequences in attribute values.
- Spawning of OS processes (e.g., sh, bash, curl, wget) by the Erlang/BEAM virtual machine hosting the Phoenix application.
- Outbound network connections from the BEAM process to unfamiliar hosts shortly after storybook playground access.
- New or modified files on disk written by the Phoenix application user without a corresponding deployment.
Detection Strategies
- Inspect Phoenix LiveView logs for handle_event/3 calls to psb-assign with non-printable or template-delimiter characters in payloads.
- Add runtime instrumentation around EEx.compile_string/2 invocations to flag templates containing unexpected expression blocks.
- Monitor for the storybook route (typically /storybook) being exposed on production hosts where it should be disabled.
Monitoring Recommendations
- Alert on child processes of the BEAM VM that are not part of normal application behavior.
- Track WebSocket frames to LiveView endpoints for anomalous payload structure or size.
- Review HTTP access logs for unauthenticated traffic to storybook routes from external IP ranges.
How to Mitigate CVE-2026-8467
Immediate Actions Required
- Upgrade phoenix_storybook to version 1.1.0 or later by updating mix.exs and running mix deps.update phoenix_storybook.
- Remove or gate the storybook router mount in any non-development environment until the upgrade is verified.
- Audit application logs for prior psb-assign events containing HEEx delimiters such as { or stray " characters.
- Rotate secrets, API tokens, and credentials stored in environment variables on any host where the playground was exposed to untrusted networks.
Patch Information
The maintainers fixed the issue in phoenix_storybook 1.1.0. The fix is referenced in GitHub Commit 56ab8464, with full details in GHSA-55hg-8qxv-qj4p and the Erlang Ecosystem Foundation CNA advisory. The patch replaces direct string interpolation in attributes_markup/1 with a safe rendering path that prevents attacker-controlled values from being parsed as HEEx expressions.
Workarounds
- Restrict the storybook route to authenticated administrative users via a Plug pipeline that enforces authentication and authorization before reaching PlaygroundPreviewLive.
- Disable the storybook mount entirely in production by guarding the router entry with if Mix.env() == :dev.
- Place the storybook endpoint behind a network ACL or VPN so unauthenticated clients cannot reach the LiveView WebSocket.
# Update phoenix_storybook to the patched release
mix deps.update phoenix_storybook
mix deps.get
mix compile --force
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


