Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-66296

CVE-2026-66296: Oaskit Reflected XSS Vulnerability

CVE-2026-66296 is a reflected XSS vulnerability in Oaskit's default error handler that allows attackers to inject malicious scripts via crafted GET links. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-66296 Overview

CVE-2026-66296 is a reflected Cross-Site Scripting (XSS) vulnerability [CWE-79] in the lud/oaskit Elixir library. The default HTML error handler in Oaskit.ErrorHandler.Default interpolates request-controlled values into an HTML error page without escaping them. Attackers can craft a GET link that triggers the error page and executes arbitrary JavaScript in the application's origin. The flaw affects oaskit versions from 0.1.0 before 0.14.1.

Critical Impact

A crafted top-level navigation link executes attacker-controlled JavaScript in the origin of any application using oaskit with default settings, exposing cookies, session tokens, and same-origin data.

Affected Products

  • lud/oaskit versions 0.1.0 through 0.14.0
  • Elixir/Phoenix applications using Oaskit.Plugs.ValidateRequest with default settings
  • Any oaskit consumer relying on Oaskit.ErrorHandler.Default for HTML error rendering

Discovery Timeline

  • 2026-08-03 - CVE-2026-66296 published to NVD
  • 2026-08-04 - Last updated in NVD database

Technical Details for CVE-2026-66296

Vulnerability Analysis

The vulnerability lives in Oaskit.ErrorHandler.Default.format_reason/4 and Oaskit.ErrorHandler.Default.reason_to_html/1 inside lib/oaskit/error_handler/default.ex. When a request's Accept header contains html, the handler renders request-validation failures as an HTML page. Request-controlled strings are interpolated directly into that page without HTML escaping.

Both the HTML error rendering and the vulnerable handler are enabled by default. Oaskit.Plugs.ValidateRequest defaults :html_errors to true and :error_handler to Oaskit.ErrorHandler.Default, so applications following the documented setup are exposed without any opt-in.

Root Cause

Two classes of untrusted input reach the HTML template unescaped. The first is object keys taken from a request body or from object/deepObject query parameters, which appear in JSON Schema error instancePath values when a schema rejects them under constraints like additionalProperties: false. The second is the raw Content-Type header, which is reflected in unsupported-media-type errors when parsing fails.

Attack Vector

Browsers send Accept: text/html on ordinary top-level navigation, so a single crafted GET link triggers the error page. No form submission, custom Content-Type, or victim-side script is required. A payload such as filter[</code></h2><script>alert(document.domain)</script>]=x terminates the enclosing markup and executes the injected script in the origin of the target application, granting access to its cookies, session, and same-origin responses.

text
     """
     <!doctype html>
     <style>#{css()}</style>
-    <title>#{message}</title>
+    <title>#{esc(message)}</title>
 
-    <h1><span class="status">HTTP ERROR #{code}</span> #{message} </h1>
+    <h1><span class="status">HTTP ERROR #{code}</span> #{esc(message)} </h1>
 
-    <p>Invalid request for operation <code>#{operation_id}</code>.</p>
+    <p>Invalid request for operation <code>#{esc(operation_id)}</code>.</p>
 
     <ol>
     #{errors}
     </ol>
     """
   end
 
+  # Escape any value that ends up in the HTML error page. Most interpolated
+  # values (parameter names, operation ids, validation messages) come from the
+  # spec, but some are derived from the request (the raw content-type in an
+  # unsupported media type error, JSON pointers built from client-supplied
+  # object keys in validation messages), so they must never be trusted as
+  # markup.
+  defp esc(value) do
+    value |> to_string() |> Plug.HTML.html_escape()
+  end

Source: GitHub Commit b70c6b2. The patch routes every interpolated value through Plug.HTML.html_escape/1 via a new esc/1 helper.

Detection Methods for CVE-2026-66296

Indicators of Compromise

  • Query strings containing HTML tag characters in bracketed object-key positions, for example filter[<script>...] or filter[</code></h2>...]
  • Request Content-Type headers containing <, >, or script substrings that reach unsupported-media-type errors
  • HTTP 4xx responses of Content-Type: text/html whose body contains reflected characters from the request URL or headers

Detection Strategies

  • Inspect web server and reverse proxy logs for GET requests to oaskit-backed routes with URL-encoded HTML metacharacters in query parameter keys.
  • Alert on responses served by Oaskit.ErrorHandler.Default that include <script> or event-handler attributes not present in the application's static templates.
  • Correlate outbound referrer traffic to oaskit endpoints against phishing or link-bait campaigns targeting authenticated users.

Monitoring Recommendations

  • Deploy WAF signatures matching XSS payloads in bracketed query parameter keys and in the Content-Type request header.
  • Log and review 400/415 responses generated by Oaskit.Plugs.ValidateRequest for anomalous content.
  • Track deployed versions of the oaskit dependency across Elixir services and flag any release below 0.14.1.

How to Mitigate CVE-2026-66296

Immediate Actions Required

  • Upgrade oaskit to version 0.14.1 or later in mix.exs and redeploy affected services.
  • Audit Phoenix and Plug pipelines for use of Oaskit.Plugs.ValidateRequest and confirm the patched version is loaded.
  • Rotate session cookies and API tokens if server logs show suspicious HTML metacharacter traffic to oaskit routes.

Patch Information

The fix is committed in b70c6b2eaf0b11bdd0bbb21b8a87dbb3d46918a1 and released in oaskit0.14.1. It introduces an esc/1 helper that pipes every interpolated value through Plug.HTML.html_escape/1 inside lib/oaskit/error_handler/default.ex. See the GitHub Security Advisory GHSA-h7xw-x8wr-xpcc and the CNA advisory for authoritative details.

Workarounds

  • Disable HTML error rendering by setting :html_errors to false on Oaskit.Plugs.ValidateRequest.
  • Replace Oaskit.ErrorHandler.Default with a custom :error_handler that returns JSON responses only.
  • Configure a strict Content-Security-Policy header with script-src 'self' and no unsafe-inline to reduce impact of reflected script execution.
bash
# Upgrade oaskit in mix.exs and refresh the dependency lock
# {:oaskit, "~> 0.14.1"}
mix deps.update oaskit
mix deps.get
mix compile

# Temporary workaround: disable HTML error rendering in the plug pipeline
# plug Oaskit.Plugs.ValidateRequest, html_errors: false

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.