| Title | owen2345 CAMALEON CMS 2.9.2 Broken Object Level Authorization (BOLA) / Insecure Direct Objec |
|---|
| Description | Camaleon CMS 2.9.2 contains an authorization flaw in the administrative media crop endpoint that allows an authenticated user with media management permission to modify the avatar metadata of an arbitrary user by controlling the saved_avatar parameter.
The vulnerable endpoint is implemented in app/controllers/camaleon_cms/admin/media_controller.rb. The controller enforces media authorization through authorize! :manage, :media, but the crop action also performs a user metadata update when the saved_avatar parameter is present. In the vulnerable implementation, the target user is selected directly from attacker-controlled input:
CamaleonCms::User.find(params[:saved_avatar]).set_meta('avatar', res['url']) if params[:saved_avatar].present?
This creates a Broken Object Level Authorization / IDOR condition. A user who is only authorized to manage media files can provide the ID of another user in saved_avatar and cause the application to update that other user's avatar. The application does not verify that the target user is the authenticated user, does not require user-management permission for cross-user avatar changes, and does not apply object-level authorization to the affected user record.
The issue is not merely CSRF. Even if CSRF protection were enforced, the server-side authorization flaw would remain: the endpoint accepts a user-controlled object identifier and applies a state-changing operation to that object without verifying whether the caller is allowed to modify it.
A vulnerable flow is:
1. An authenticated user has permission to manage media.
2. The user sends a request to /admin/media/crop.
3. The request includes saved_avatar set to another user's ID.
4. The server crops/uploads the provided image.
5. The server writes the resulting media URL to the avatar metadata of the user identified by saved_avatar.
Example proof-of-concept request:
GET /admin/media/crop?cp_img_path=/tmp/poc-avatar.png&name=poc-avatar.png&formats=png&ic_w=10&ic_h=10&ic_x=0&ic_y=0&saved_avatar=4 HTTP/1.1
Host: localhost:3000
Cookie: [authenticated session of a user with media management permission]
In this example, saved_avatar=4 identifies a different user account. If the authenticated caller has media management permission, the vulnerable code updates the avatar metadata of user ID 4 without requiring permission to manage that user.
A JavaScript proof-of-concept in an authenticated browser context is:
fetch('/admin/media/crop?cp_img_path=/tmp/poc-avatar.png&name=poc-avatar.png&formats=png&ic_w=10&ic_h=10&ic_x=0&ic_y=0&saved_avatar=4', {
credentials: 'include'
})
.then(r => r.text())
.then(console.log)
The endpoint returns the uploaded/cropped media path, and the victim user's avatar metadata is changed to that returned path.
Impact:
This allows horizontal privilege abuse between users within the CMS. A lower-privileged user with media-management access can alter another user's avatar without consent. This violates object-level authorization and the principle of least privilege. Depending on how avatars are displayed in the CMS, the issue may enable visual impersonation, social engineering, defacement of user profile data, or confusion in administrative workflows.
The impact can be increased when chained with a stored XSS issue in media uploads. If an attacker can upload an HTML file that executes JavaScript in the CMS origin, the uploaded file can trigger the same authenticated fetch request from the victim/admin browser:
<body onpointerdown="
fetch('/admin/media/crop?cp_img_path=/tmp/poc-avatar.png&name=poc-avatar.png&formats=png&ic_w=10&ic_h=10&ic_x=0&ic_y=0&saved_avatar=4', {
credentials: 'include'
})
">
Click here
</body>
This chain demonstrates that JavaScript executing in the CMS origin can invoke the vulnerable endpoint using the authenticated user's session and alter another user's avatar.
Recommended fix:
The target user should be resolved within the current site scope, and the application should enforce object-level authorization before processing the crop/upload. A user should only be allowed to update their own avatar unless they also have user-management permission.
A safe implementation pattern is:
saved_avatar_user = nil
if params[:saved_avatar].present?
saved_avatar_user = current_site.users_include_admins.find(params[:saved_avatar])
authorize! :manage, :users unless saved_avatar_user.id == cama_current_user.id
end
After the upload succeeds:
saved_avatar_user&.set_meta('avatar', res['url'])
This ensures:
- the target user belongs to the current site scope;
- users with only media permission can update only their own avatar;
- updating another user's avatar requires manage :users;
- authorization happens before image processing;
- unauthorized requests do not create cropped/uploaded files.
Regression tests should verify:
1. A media manager can update their own avatar.
2. A media manager cannot update another user's avatar.
3. A user with both media and user-management permissions can update another same-site user's avatar.
4. The victim user's avatar remains unchanged after an unauthorized request |
|---|
| User | 7acini (UID 100641) |
|---|
| Submission | 08/18/2026 03:52 (1 month ago) |
|---|
| Moderation | 09/28/2026 22:04 (1 month later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 411164 [owen2345 Camaleon CMS up to 2.9.2 Media Crop media_controller.rb crop saved_avatar authorization] |
|---|
| Points | 17 |
|---|