GHSA-h7x6-9mqf-vgmx: 
Ruby analisi e mitigazione delle vulnerabilità

Summary

?set_locale= wrote the request's value into Avo.configuration.locale, a setting shared by every request the Ruby process serves. It did so before Avo's authenticate block ran.

  • An unknown locale (?set_locale=zz) was stored, and every later Avo request from every user raised I18n::InvalidLocale (HTTP 500) until the process restarted.
  • A valid locale changed the admin language for every user.
  • In apps that authenticate through config.authenticate_with rather than a route constraint, both worked without signing in.

Patches

Fixed in avo 4.3.1 and avo 3.33.1. Avo 3 apps that use avo-pro or avo-advanced also need 3.33.1 of avo-pro, avo-advanced, avo-dashboards, avo-menu and avo-dynamic_filters, because they pin the avo version exactly. Run bundle update avo together with those gems. Unknown locales in set_locale and force_locale are now ignored, and set_locale is stored only after the authenticate block lets the request through: avo-hq/avo#4886 and avo-hq/avo#4893 (4.x), avo-hq/avo#4894 (3.x).

Workarounds

Mount Avo behind a route-level authentication constraint (for example Devise's authenticate :user do ... end), so signed-out requests never reach Avo's controllers. Signed-in users can still trigger the bug until you upgrade.

Original report

Avo — Global Avo.configuration.locale mutation via params[:set_locale]

Summary

Avo::BaseApplicationController#set_avo_locale is registered as an around_action and writes Avo.configuration.locale from params[:set_locale]:


# app/controllers/avo/base_application_controller.rb
around_action :set_avo_locale
...
def set_avo_locale(&action)
  locale = Avo.configuration.default_locale
  if params[:set_locale].present?
    locale = params[:set_locale]
    Avo.configuration.locale = locale            # <-- mutates global config
  end
  I18n.with_locale(locale, &action)
end

Avo.configuration is the application-wide singleton built in Avo::Configuration and reused across every request handled by the same Ruby process. Writing to Avo.configuration.locale therefore persists the value globally — it affects every other in-flight and future request, served to every other user, until the process is restarted or a subsequent request explicitly resets it. A second issue is callback ordering: set_avo_locale is an around_action registered before _authenticate! in the BaseApplicationController callback chain, so the mutation happens before authentication. Whether it is reachable pre-auth depends on the host application's Avo.configuration.authenticate proc — anything that renders before redirecting (or any host that allows public access to a single avo URL such as a status / health endpoint) gives unauthenticated attackers a write primitive against Avo.configuration.locale.

Affected versions

All current 3.x releases up to 3.31.2 and the v4.0.0 betas are affected.

Exploit conditions

  • Any avo URL that runs the set_avo_locale around_action (i.e. anything inheriting BaseApplicationController — effectively the whole engine).
  • For low-privilege authenticated abuse: any authenticated session.
  • For unauthenticated abuse: a host whose authenticate proc lets the around_action complete before redirecting (the around_action runs to its first yield before _authenticate!'s before_action is invoked, so the mutation always lands).

PoC

A reproducible RSpec request spec is provided at spec/requests/avo/locale_global_state_spec.rb:

it "persists the attacker-supplied locale on the global Avo.configuration" do
  original = Avo.configuration.locale
  get "/admin?set_locale=xx-poisoned"
  expect(Avo.configuration.locale).to eq("xx-poisoned")
  Avo.configuration.locale = original
end

End-to-end with curl:

curl -b session.txt "https://target/admin?set_locale=xx-poisoned"

# every subsequent request served by the same Puma worker now starts

# with Avo.configuration.locale == "xx-poisoned" (until another set_locale

# overrides it or the worker restarts).

Impact

  • Persistent corruption of the application-wide locale setting. The most direct fallout is that translation lookups using Avo.configuration.locale (rather than per-request I18n.locale) return missing-translation strings or fall back unpredictably for every user.
  • More importantly, this is a confidentiality-and-integrity-grade bug pattern: query string params should not write to global singletons. Any future code that reads Avo.configuration.locale (e.g. for caching keys, log routing, default behavior) inherits the corruption automatically.
  • Combining locale corruption with params[:force_locale] (set_force_locale) and other I18n.with_locale paths can be used to force missing-translation behavior for other admins (denial-of-service of the UI for the attacker's chosen scope). CVSS v3.1 estimate: 3.7 / Low — AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N. Higher if reachable pre-auth.

Suggested patch

Treat params[:set_locale] as request-local input, never write to Avo.configuration:

def set_avo_locale(&action)
  locale = params[:set_locale].presence || Avo.configuration.default_locale
  I18n.with_locale(locale, &action)
end

If a deployment legitimately needs to "remember" a user's locale across requests, that belongs in the user record or the session — not in a process-global singleton. Optionally, restrict the value against I18n.available_locales so a malformed locale doesn't poison I18n.with_locale:

def set_avo_locale(&action)
  requested = params[:set_locale].to_s
  locale = if I18n.available_locales.map(&:to_s).include?(requested)
    requested
  else
    Avo.configuration.default_locale
  end
  I18n.with_locale(locale, &action)
end

A regression test is included with the PoC above.

Disclosure

Reported privately via GitHub Security Advisory.


Fonte: NVD

Vulnerabilità correlate di Ruby:

CVE ID

Gravità

Punteggio

Tecnologie

Nome del componente

Exploit CISA KEV

Dispone di patch

Data di pubblicazione

CVE-2026-110264CRITICAL10
  • Ruby logoRuby
  • rubygem-rdoc
NoSìOct 22, 2026
GHSA-h7x6-9mqf-vgmxHIGH8.2
  • Ruby logoRuby
  • avo
NoSìOct 22, 2026
GHSA-x65r-p6hf-94hvMEDIUM6.5
  • Ruby logoRuby
  • avo
NoSìOct 22, 2026
GHSA-58rx-96gf-w92xMEDIUM6.1
  • Ruby logoRuby
  • ransack
NoSìOct 25, 2026
CVE-2026-63183LOWN/D
  • Ruby logoRuby
  • omniauth
NoNoOct 22, 2026

Valutazione gratuita delle vulnerabilità

Valuta la tua postura di sicurezza del cloud

Valuta le tue pratiche di sicurezza del cloud in 9 domini di sicurezza per stabilire un benchmark del tuo livello di rischio e identificare le lacune nelle tue difese.

Richiedi valutazione

Ulteriori risorse Wiz

Richiedi una demo personalizzata

Pronti a vedere Wiz in azione?

"La migliore esperienza utente che abbia mai visto offre piena visibilità ai carichi di lavoro cloud."
David EstlickCISO (CISO)
"Wiz fornisce un unico pannello di controllo per vedere cosa sta succedendo nei nostri ambienti cloud."
Adam FletcherResponsabile della sicurezza
"Sappiamo che se Wiz identifica qualcosa come critico, in realtà lo è."
Greg PoniatowskiResponsabile della gestione delle minacce e delle vulnerabilità