{"id":"GHSA-qc5p-3mg5-9fh8","summary":"Avo: Broken Access Control Through Unauthorized Execution of Arbitrary Action Classes Across Resources","details":"### Summary\n\nA critical Broken Access Control vulnerability was identified in the `ActionsController` of the Avo framework (v3.x). Due to insecure action lookup logic, an authenticated user can execute any Action class (descendants of `Avo::BaseAction`) on any resource, even if the action is not registered for that specific resource. This leads to Privilege Escalation and unauthorized data manipulation across the entire application.\n\n### Details\n\nThe vulnerability exists in the `action_class` method within `app/controllers/avo/actions_controller.rb`.\n\n#### Vulnerable Code\n\n```ruby\ndef action_class\n  # It searches through ALL descendants of BaseAction without resource validation\n  Avo::BaseAction.descendants.find do |action|\n    action.to_s == params[:action_id]\n  end\nend\n```\n\nThe controller identifies the action class to execute solely based on the `params[:action_id]` by searching through all `BaseAction` descendants. It fails to verify whether the requested action is actually permitted or registered for the resource context specified in the request URL (e.g., `/admin/resources/posts/actions`).\n\nConsequently, an attacker can invoke sensitive actions (e.g., `Avo::Actions::ToggleAdmin`) through an unrelated resource endpoint (e.g., `Post`), bypassing the intended resource-action mapping.\n\n### Impact\n\nThis flaw results in significant security risks:\n\n- **Privilege Escalation:** An authenticated user with low privileges can execute administrative actions (like toggling admin roles) to escalate their own or others' permissions.\n- **Unauthorized Operations:** Actions designed for restricted resources can be triggered against any record ID in the database.\n- **Data Integrity Compromise:** Attackers can perform unauthorized destructive operations (e.g., Delete, Archive, or Update) on records they should not have access to.\n\n### Proof of Concept (PoC)\n\n**Steps to Reproduce:**\n\n01. Log in to the Avo admin panel with limited permissions.\n02. Identify a target record ID (e.g., User ID: 1) and a sensitive action class (e.g., `Avo::Actions::ToggleAdmin`).\n03. Send a POST request to a resource endpoint where the target action is not registered:\n    - **URL:** `POST /admin/resources/posts/actions`\n    - **Payload:** `action_id=Avo::Actions::ToggleAdmin&fields[avo_resource_ids]=1`\n04. The server executes the `ToggleAdmin` logic on User 1, even though the request was made through the `posts` resource context.\n\n**PoC Script Snippet:**\n\n```python\n# Simulating the unauthorized action execution\ndata = {\n    'action_id': 'Avo::Actions::ToggleAdmin',\n    'fields[avo_resource_ids]': '1', # Target Record ID\n    'authenticity_token': csrf_token\n}\nresponse = session.post(f\"{BASE_URL}/admin/resources/posts/actions\", data=data)\n```\n\n### Remediation\n\nRestrict the action lookup to only those actions explicitly registered for the current resource context:\n\n```ruby\ndef action_class\n  # Validate that the action is registered for the current resource\n  @resource.get_actions.find do |action|\n    action.to_s == params[:action_id]\n  end\nend\n```\n\n### Discoverer\n\nIllunight","aliases":["CVE-2026-42205"],"modified":"2026-05-13T13:52:51.143955Z","published":"2026-04-24T16:11:28Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-04-24T16:11:28Z","nvd_published_at":"2026-05-08T22:16:31Z","cwe_ids":["CWE-284","CWE-639"],"severity":"HIGH"},"references":[{"type":"WEB","url":"https://github.com/avo-hq/avo/security/advisories/GHSA-qc5p-3mg5-9fh8"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42205"},{"type":"PACKAGE","url":"https://github.com/avo-hq/avo"},{"type":"WEB","url":"https://github.com/avo-hq/avo/releases/tag/v3.31.2"}],"affected":[{"package":{"name":"avo","ecosystem":"RubyGems","purl":"pkg:gem/avo"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.31.2"}]}],"versions":["0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.3.1","0.3.2","0.4.1","0.4.10","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","0.5.0.beta1","0.5.0.beta10","0.5.0.beta11","0.5.0.beta12","0.5.0.beta13","0.5.0.beta14","0.5.0.beta15","0.5.0.beta2","0.5.0.beta3","0.5.0.beta4","0.5.0.beta5","0.5.0.beta6","0.5.0.beta7","0.5.0.beta8","0.5.0.beta9","1.0.0","1.0.1","1.0.2","1.0.4","1.0.5","1.1.0","1.1.0.pre.1","1.10.0","1.10.1","1.10.2","1.10.3","1.11.0","1.11.1","1.11.2","1.11.3","1.11.4","1.11.5","1.11.6","1.12.0","1.12.1","1.12.2","1.12.3","1.12.4","1.13.0","1.13.1","1.13.2","1.13.3","1.14.0","1.15.0","1.15.0.pre.1","1.16.0","1.16.1","1.16.2","1.16.3","1.16.4","1.17.0","1.17.1","1.18.0","1.18.0.pre.1","1.18.0.pre.2","1.18.0.pre.3","1.18.1","1.18.2","1.18.2.pre.0","1.19.0","1.19.1.pre.1","1.19.1.pre.10","1.19.1.pre.11","1.19.1.pre.2","1.19.1.pre.3","1.19.1.pre.4","1.19.1.pre.5","1.19.1.pre.6","1.19.1.pre.7","1.19.1.pre.8","1.19.1.pre.9","1.2.10","1.2.11.pre.1","1.2.11.pre.2","1.2.11.pre.3","1.2.11.pre.4","1.2.2","1.2.3","1.2.4","1.2.5","1.2.6","1.2.6.pre.1","1.2.7","1.2.8","1.2.9","1.20.1","1.20.2.pre.1","1.20.2.pre.2","1.21.0","1.21.0.pre.1","1.21.1.pre.1","1.22.0","1.22.0.pre.1","1.22.1","1.22.1.pre.1","1.22.1.pre.2","1.22.2","1.22.3","1.22.4","1.23.0","1.24.0","1.24.1","1.24.2","1.25.0","1.25.1","1.25.2","1.3.0","1.3.0.pre.1","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.3.5.pre.1","1.4.0","1.4.0.pre.1","1.4.1","1.4.2","1.4.3","1.4.4","1.4.4.pre.1","1.4.5.pre.1","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.6.0","1.6.1","1.6.2.pre.1","1.6.3.pre.1","1.6.3.pre.2","1.6.3.pre.3","1.6.4.pre.1","1.7.0","1.7.1","1.7.2","1.7.3","1.7.3.pre.1","1.8.0","1.8.1","1.8.2","1.8.3","1.8.4","1.9.0","1.9.1","2.0.0","2.1.0","2.1.1","2.1.2.pre1","2.1.2.pre2","2.10.0","2.10.2","2.10.3.pre.1","2.11.0","2.11.1","2.11.1.pre.1","2.11.1.pre.2","2.11.1.pre.3","2.11.2.pre.1","2.11.2.pre.2","2.11.2.pre.3","2.11.3.pre.1","2.11.3.pre.2","2.11.3.pre.3","2.12.0","2.12.1.pre.1","2.13.0","2.13.1","2.13.2.pre.1","2.13.2.pre.2","2.13.3.pre.1","2.13.3.pre.2","2.13.3.pre.3","2.13.3.pre.4","2.13.4.pre.1","2.13.5.pre.1","2.13.5.pre.2","2.13.6.pre.1","2.13.6.pre.2","2.14.0","2.14.1","2.14.1.pre.1","2.14.2","2.14.2.pre.1","2.14.3.pre.1.branding","2.14.3.pre.2.tailwindcss","2.14.3.pre.3.jsbundling","2.14.3.pre.4.tosqlfix","2.14.3.pre.5.nosprockets","2.14.3.pre.6.nosprockets","2.14.3.pre.7.polytranslations1","2.15.0","2.15.1","2.15.2","2.15.2.pre.1","2.15.3","2.15.3.pre.1.data.attrs.to.sidebar.items","2.16.0","2.16.1.pre.1.nativefields","2.17.0","2.17.1.pre.1.zeitwerk.eager.load.dir","2.17.1.pre.2.customauthorizationclients","2.17.1.pre.3","2.17.1.pre.4.issue.1342","2.17.1.pre.5.stackedlayout","2.18.0","2.18.1","2.18.1.pre.1.eagerloaddirs","2.19.0","2.2.0","2.2.1","2.2.2","2.20.0","2.21.0","2.21.1.pre.issue1444","2.21.1.pre.issue1450","2.21.1.pre.pr1476","2.21.1.pre.pr1484","2.21.2.pre.pr1486","2.21.3.pre.pr1489","2.22.0","2.23.0","2.23.1","2.23.2","2.23.3.pre.1.pr1529","2.24.0","2.24.1","2.25.0","2.25.1.pre.1.pr1579","2.26.0","2.26.1.pr1584.pre.1","2.26.2.pre.pr1579","2.26.3.pre.pr1601","2.27.0","2.27.1","2.27.2.pre.pr1606","2.28.0","2.28.1.pre.pr1642","2.28.2.pre.pr1642","2.28.3.pre.pr1646","2.29.0","2.29.1","2.29.1.pre.pr1652","2.3.0","2.3.1.pre.1","2.3.1.pre.2","2.3.1.pre.3","2.3.1.pre.4","2.3.1.pre.5","2.3.1.pre.6","2.30.0","2.30.1","2.30.1.pre1.pr1683","2.30.1.pre2.pr1683","2.30.1.pre3.pr1683","2.30.1.pre4.pr1683","2.30.2","2.31.0","2.32.0","2.32.1","2.32.2","2.32.3","2.32.4","2.32.5","2.32.6","2.33.0","2.33.1","2.33.2","2.33.3","2.33.3.pre.1","2.33.3.pre.2","2.34.0","2.34.1","2.34.2","2.34.3","2.34.4","2.34.4.pre.1","2.34.5","2.34.6","2.34.7.pre.1","2.35.0","2.36.0","2.36.1","2.36.2","2.36.3","2.37.0","2.37.1","2.37.2","2.38.0","2.39.0","2.4.0","2.4.1","2.40.0","2.41.0","2.42.0","2.42.1","2.42.2","2.43.0","2.44.0","2.45.0","2.46.0","2.47.0","2.48.0","2.49.0","2.5.0","2.5.1","2.5.2.pre.1","2.5.2.pre.2","2.5.2.pre.3","2.5.2.pre.4","2.5.2.pre.5","2.5.2.pre.6","2.5.2.pre.7","2.50.0","2.51.0","2.52.0","2.53.0","2.6.0","2.6.1.pre.1","2.6.1.pre.2","2.7.0","2.7.1.pre.1","2.8.0","2.9.0","2.9.1.pre1","2.9.1.pre2","2.9.1.pre3","2.9.1.pre4","2.9.1.pre5","2.9.1.pre6","2.9.1.pre7","2.9.2.pre1","3.0.0.beta1","3.0.0.pre1","3.0.0.pre10","3.0.0.pre11","3.0.0.pre12","3.0.0.pre13","3.0.0.pre14","3.0.0.pre15","3.0.0.pre16","3.0.0.pre17","3.0.0.pre18","3.0.0.pre19","3.0.0.pre2","3.0.0.pre3","3.0.0.pre4","3.0.0.pre5","3.0.0.pre6","3.0.0.pre7","3.0.0.pre8","3.0.0.pre9","3.0.1.beta1","3.0.1.beta10","3.0.1.beta11","3.0.1.beta12","3.0.1.beta13","3.0.1.beta14","3.0.1.beta15","3.0.1.beta16","3.0.1.beta17","3.0.1.beta18","3.0.1.beta19","3.0.1.beta2","3.0.1.beta20","3.0.1.beta21","3.0.1.beta22","3.0.1.beta23","3.0.1.beta24","3.0.1.beta3","3.0.1.beta4","3.0.1.beta5","3.0.1.beta6","3.0.1.beta7","3.0.1.beta8","3.0.1.beta9","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.10.0","3.10.1","3.10.10","3.10.2","3.10.3","3.10.4","3.10.5","3.10.6","3.10.7","3.10.8","3.10.9","3.11.0","3.11.1","3.11.10","3.11.2","3.11.3","3.11.4","3.11.5","3.11.6","3.11.7","3.11.8","3.11.9","3.12.0","3.13.0","3.13.1","3.13.2","3.13.3","3.13.4","3.13.5","3.13.6","3.13.7","3.14.0","3.14.1","3.14.2","3.14.3","3.14.4","3.14.5","3.15.0","3.15.1","3.15.2","3.15.3","3.15.4","3.15.5","3.15.6","3.15.7","3.16.0","3.16.1","3.16.2","3.16.3","3.16.4","3.16.5","3.16.6","3.17.0","3.17.1","3.17.1.tw4","3.17.2","3.17.2.tw4","3.17.3","3.17.3.tw4","3.17.4","3.17.4.tw4","3.17.5","3.17.5.tw4","3.17.6","3.17.6.tw4","3.17.7","3.17.8","3.17.8.tw4","3.17.9","3.17.9.beta1","3.17.9.beta2","3.17.9.tw4","3.18.0","3.18.0.tw4","3.18.1","3.18.1.tw4","3.18.2","3.18.2.tw4","3.19.0","3.19.1","3.19.2","3.19.3","3.2.0","3.2.1","3.2.2","3.2.3","3.20.0","3.20.1","3.20.2","3.20.3","3.21.0","3.21.1","3.22.0","3.22.2","3.22.3","3.22.4","3.22.5","3.23.0","3.23.1","3.24.0","3.24.1","3.25.0","3.25.1","3.25.2","3.25.3","3.26.0","3.26.2","3.26.3","3.26.4","3.27.0","3.28.0","3.29.0","3.29.1","3.3.0","3.3.1","3.3.2","3.3.3","3.3.4","3.3.5","3.3.6","3.30.0","3.30.1","3.30.2","3.30.3","3.30.4","3.31.0","3.31.1","3.4.0","3.4.1","3.4.2","3.4.3","3.4.4","3.5.0","3.5.1","3.5.2","3.5.3","3.5.4","3.5.5","3.5.6","3.5.6.beta1","3.5.7","3.5.8","3.6.0","3.6.1","3.6.2","3.6.3","3.6.4","3.7.0","3.7.1","3.7.2","3.7.3","3.7.4","3.8.0","3.8.1","3.8.2","3.9.0","3.9.1","3.9.2"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-qc5p-3mg5-9fh8/GHSA-qc5p-3mg5-9fh8.json"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"}]}