
Camaleon CMS 2.9.2 - Improper authorization in draft autosave endpoint
5,1
Medium
Detected by

Fluid Attacks AI SAST Scanner
Disclosed by
Oscar Naveda
Summary
Full name
Camaleon CMS 2.9.2 - Improper authorization in draft autosave endpoint
Code name
State
Public
Release date
Affected product
Camaleon CMS
Vendor
Camaleon CMS
Affected version(s)
2.9.2
Package manager
RubyGems
Vulnerability name
Improper authorization control for web services
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
CVSS v4.0 base score
5.1
Exploit available
Yes
CVE ID(s)
Description
Camaleon CMS 2.9.2 contains an improper authorization vulnerability in the administrator draft autosave endpoint. A low-privileged authenticated user can send an arbitrary post_id to POST /admin/post_type/<POST_TYPE_ID>/drafts and overwrite the draft associated with another user's post.
The vulnerable controller trusts the client-controlled post_id parameter to locate an existing draft and then updates that draft without checking whether the current user owns, created, or is authorized to edit the parent post. This compromises content integrity because malicious draft changes can later be reviewed or published by an authorized editor or administrator.
Vulnerability
Root cause
The drafts route is exposed under the admin post type namespace (
config/routes/admin.rb:17-33):The admin base controller only requires an authenticated user (
app/helpers/camaleon_cms/session_helper.rb:153-155):The draft controller must therefore perform resource-level authorization before mutating content.
Normal post actions enforce authorization, but draft actions do not (
app/controllers/camaleon_cms/admin/posts_controller.rb:74-132):CamaleonCms::Admin::Posts::DraftsController#createand#updatedo not perform equivalentauthorize!checks.The vulnerable draft lookup trusts a user-controlled parent post id (
app/controllers/camaleon_cms/admin/posts/drafts_controller.rb:11-23):The query is not scoped to
cama_current_user,@post_type.posts, or a parent post that the current user can update.The server assigns the attacker-supplied parent id to the draft data (
app/controllers/camaleon_cms/admin/posts/drafts_controller.rb:54-67):
Confirmed source-to-sink path
Source: authenticated attacker controls
post_idandpost[...]fields in the draft autosave request.Route:
POST /admin/post_type/<POST_TYPE_ID>/draftsreachesCamaleonCms::Admin::Posts::DraftsController#create.Lookup:
CamaleonCms::Post.drafts.where(post_parent: params[:post_id]).firstretrieves the draft for the supplied parent post id.Mutation:
@post_draft.attributes = @post_datareplaces draft fields with attacker-controlled values.Persistence:
@post_draft.save(validate: false)stores the modified draft without validating ownership or edit permissions.
Authorization bypass
The intended permission model is defined in app/models/camaleon_cms/ability.rb:38-64. A user with only post-type edit privileges can update posts they own, while edit_other is required to update another user's content. The draft endpoint bypasses that model because it never calls authorize! :update, parent_post or scopes the draft lookup to posts the current user may edit.
Relevant code:
config/routes/admin.rb:17-33(draft routes)app/helpers/camaleon_cms/session_helper.rb:153-155(authentication only)app/controllers/camaleon_cms/admin/posts_controller.rb:74-132(authorization on normal create/update flows)app/controllers/camaleon_cms/admin/posts/drafts_controller.rb:11-23(vulnerable draft lookup and save)app/controllers/camaleon_cms/admin/posts/drafts_controller.rb:54-67(server-side draft params)app/models/camaleon_cms/ability.rb:38-64(intended post authorization rules)app/assets/javascripts/camaleon_cms/admin/_post.js:21-31(client-side autosave sendspost_id)app/views/camaleon_cms/admin/posts/form.html.erb:80-85(client initializes draftpost_idand endpoint)
PoC
Preconditions
A Camaleon CMS 2.9.2 instance.
User A has permissions to create or edit content and has a post with an associated draft.
User B is authenticated with lower privileges and is not authorized to edit User A's post.
User B has a valid session cookie and CSRF token for the admin area.
Step 1 - Create a victim draft
As User A, create or edit a post and allow Camaleon CMS to generate a draft. Record the parent post id:
Step 2 - Send a forged draft autosave request
As User B, send a request to the draft endpoint with User A's parent post id:
Expected response:
Step 3 - Verify unauthorized modification
Log back in as User A and inspect the draft associated with the original post. The title, slug, and content have been overwritten with the values supplied by User B.
Expected result:
User B cannot normally update User A's post through
PostsController#update.User B can still overwrite the draft for User A's post through
DraftsController#createby supplying User A'spost_id.
Evidence of Exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-10715 to refer to this issue from now on.
System Information
Camaleon CMS
Version: 2.9.2
Operating System: Any
References
Github Repository: https://github.com/owen2345/camaleon-cms
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Oscar Naveda from Fluid Attacks' Offensive Team using the AI SAST Scanner.
Timeline
Vulnerability discovered
Vendor contacted
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.













