Skip to main content

Avo CVE-2026-55518

| EUVDEUVD-2026-45334 CRITICAL
Authorization Bypass Through User-Controlled Key (CWE-639)
2026-06-17 https://github.com/avo-hq/avo GHSA-8fq9-273g-6mrg
9.6
CVSS 3.1 · Vendor: https://github.com/avo-hq/avo
Share

Severity by source

Vendor (https://github.com/avo-hq/avo) PRIMARY
9.6 CRITICAL
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
vuln.today AI
9.6 CRITICAL

Network-reachable Avo endpoint (AV:N), single crafted POST (AC:L), any authenticated Avo user suffices (PR:L), no UI; scope changes because Avo's auth boundary is bypassed to affect host-app tenancy (S:C), high C/I, no availability impact.

3.1 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N

Primary rating from Vendor (https://github.com/avo-hq/avo).

CVSS VectorVendor: https://github.com/avo-hq/avo

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
Jun 18, 2026 - 01:41 vuln.today
Analysis Generated
Jun 18, 2026 - 01:41 vuln.today

DescriptionCVE.org

Summary

A critical missing authorization flaw exists in Avo's association attach workflow. The UI and GET /resources/:resource/:id/:related/new path can check attach_<association>?, but the actual write endpoint, POST /resources/:resource/:id/:related, does not run the same authorization check before mutating the association.

As a result, an authenticated low-privileged Avo user can bypass hidden/disabled attach controls and directly attach related records to a parent record by sending a crafted POST request. In applications where associations represent teams, tenants, roles, projects, users, memberships, ownership, or other authorization-bearing relationships, this can lead to privilege escalation and cross-tenant data exposure.

Details

The association attach route writes relationships through Avo::AssociationsController#create:

ruby
# config/routes.rb
post "/:resource_name/:id/:related_name", to: "associations#create", as: "associations_create"

The controller registers an attach authorization callback only for new, not for create:

ruby
# app/controllers/avo/associations_controller.rb
before_action :set_attachment_record, only: [:create, :destroy]
before_action :authorize_index_action, only: :index
before_action :authorize_attach_action, only: :new
before_action :authorize_detach_action, only: :destroy

The new action is only the form-rendering step. The actual mutation happens in create:

ruby
def create
  if create_association
    create_success_action
  else
    create_fail_action
  end
end

create_association then attaches the attacker-supplied related record to the parent:

ruby
def create_association
  association_name = BaseResource.valid_association_name(@record, association_from_params)

  perform_action_and_record_errors do
    if through_reflection? && additional_params.present?
      new_join_record.save
    elsif has_many_reflection? || through_reflection?
      @record.send(association_name) << @attachment_record
    else
      @record.send(:"#{association_name}=", @attachment_record)
      @record.save!
    end
  end
end

The only attach-specific authorization helper is:

ruby
def authorize_attach_action
  authorize_if_defined "attach_#{@field.id}?"
end

Because this helper is bound only to new, a policy that denies attach_users?, attach_teams?, attach_roles?, or similar methods blocks the UI/form path but does not protect the write path.

This is inconsistent with the detach path, which does authorize the mutating destroy action:

ruby
before_action :authorize_detach_action, only: :destroy

The bug is especially dangerous because Avo already treats association authorization as an access-control boundary in UI components:

ruby
# lib/avo/concerns/checks_assoc_authorization.rb
method_name = :"#{policy_method}_#{association_name}?".to_sym

if service.has_method?(method_name, raise_exception: false)
  service.authorize_action(method_name, record:, raise_exception: false)
else
  !Avo.configuration.explicit_authorization
end

However, server-side enforcement is missing on the actual attach POST endpoint.

Proof of Concept

Prerequisites:

  1. A Rails application mounts Avo, for example at /admin.
  2. Avo authorization is enabled.
  3. A low-privileged user can authenticate to Avo.
  4. A parent record and a related record are both reachable by ID.
  5. The relevant policy denies attaching the relationship, for example:
ruby
def attach_users?
  false
end

Example target scenario:

  • Parent resource: projects
  • Parent ID: 1
  • Related association: users
  • Related user ID to attach: 42
  • Expected policy: low-privileged users must not be able to attach users to projects.

The UI/form request may be blocked:

http
GET /admin/resources/projects/1/users/new

But the direct write endpoint can still be invoked:

http
POST /admin/resources/projects/1/users
Content-Type: application/x-www-form-urlencoded

authenticity_token=<CSRF>&fields[related_id]=42

Run the attached PoC:

bash
python poc_avo_association_attach_bypass.py \
  --base-url http://localhost:3000 \
  --avo-root /admin \
  --cookie "_app_session=<LOW_PRIVILEGED_SESSION_COOKIE>" \
  --parent-resource projects \
  --parent-id 1 \
  --related-name users \
  --related-id 42 \
  --check-new

If GET /new is forbidden or redirected but the direct POST succeeds, the authorization bypass is confirmed.

To perform the actual attach:

bash
python poc_avo_association_attach_bypass.py \
  --base-url http://localhost:3000 \
  --avo-root /admin \
  --cookie "_app_session=<LOW_PRIVILEGED_SESSION_COOKIE>" \
  --parent-resource projects \
  --parent-id 1 \
  --related-name users \
  --related-id 42 \
  --confirm-attach

Expected vulnerable result:

  • The low-privileged user can attach the related record despite attach_<association>? being denied.
  • The parent record now includes the related record.

Impact

This vulnerability allows unauthorized relationship manipulation through Avo.

Depending on the affected association, the impact can include:

  • Privilege escalation by attaching a user to an admin group, privileged project, tenant, organization, role, or membership record.
  • Cross-tenant data exposure when tenant/user/project membership determines record visibility.
  • Integrity loss by changing ownership, assignment, access-control relationships, or business workflow state.
  • Policy bypass even when Avo UI controls correctly hide the attach button or deny the attach form.

Recommended Fix

Enforce attach authorization on the mutating endpoint.

At minimum:

ruby
before_action :authorize_attach_action, only: [:new, :create]

Additionally:

  1. Authorize against the parent record and the selected related record before writing the relationship.
  2. Ensure create fails closed when attach_<association>? is missing and explicit_authorization is enabled.
  3. Add regression tests that directly POST to /resources/:resource_name/:id/:related_name while attach_<association>? returns false.
  4. Verify has_many, has_one, has_many :through, and has_and_belongs_to_many association paths all enforce the same server-side authorization.

AnalysisAI

Authorization bypass in Avo (Ruby on Rails admin framework) versions <= 3.32.0 and 4.0.0.beta.1 through 4.0.0.beta.50 allows authenticated low-privileged users to attach arbitrary related records to parent resources via a direct POST to the associations endpoint, bypassing the attach_<association>? policy enforced only on the form-rendering GET. Publicly available exploit code exists (Python PoC in the GHSA advisory), and in deployments where associations encode teams, tenants, roles, or memberships, exploitation yields privilege escalation and cross-tenant data exposure.

Technical ContextAI

Avo is a Ruby on Rails admin panel framework distributed as the avo RubyGem. The flaw sits in Avo::AssociationsController where before_action :authorize_attach_action is registered only for the :new action (form rendering) but not for :create, the action bound to POST /resources/:resource_name/:id/:related_name that actually mutates the ActiveRecord association via <<, =, or join-record save. This is a classic CWE-639 (Authorization Bypass Through User-Controlled Key / IDOR-class) issue, made worse by the asymmetry with the detach path which correctly authorizes :destroy. Because Avo's checks_assoc_authorization concern is treated by the UI as a real access boundary, downstream applications reasonably expect server-side enforcement that does not exist.

RemediationAI

Vendor-released patch: upgrade avo to 3.32.1 (3.x users) or 4.0.0.beta.51 (4.x beta users) as published in GHSA-8fq9-273g-6mrg (https://github.com/avo-hq/avo/security/advisories/GHSA-8fq9-273g-6mrg). If immediate upgrade is not possible, apply the vendor's recommended fix by monkey-patching Avo::AssociationsController to add before_action :authorize_attach_action, only: [:new, :create] and ensure explicit_authorization is enabled so missing attach_<association>? methods fail closed; the side effect is that any policy currently relying on the absence of the helper to implicitly allow attaches will now block, requiring an audit of policy classes. As a network-layer compensating control, restrict the Avo mount path (e.g. /admin) to trusted networks or block POST /admin/resources/:resource/:id/:related from non-admin user sessions at a reverse proxy or WAF, accepting that this disables legitimate attach workflows for affected roles.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

CVE-2026-55518 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy