Files
chatwoot/app/controllers/api/v1/accounts/custom_attribute_definitions_controller.rb
5c6ea78ce6 fix(security): Enforce admin authorization on custom attribute definitions API (#14392)
Custom attribute definitions can now only be created, edited, or deleted
by administrators, matching the existing settings UI restriction.
Previously, an agent could call the `custom_attribute_definitions` API
directly and modify account configuration that they couldn't reach
through the dashboard — a Broken Access Control vulnerability reported
externally.

Fixes
https://linear.app/chatwoot/issue/CW-7038/broken-access-control-on-custom-attribute-definitions-api

## How to test

1. Sign in as an agent.
2. Try to create a custom attribute by calling `POST
/api/v1/accounts/<id>/custom_attribute_definitions` directly (the
settings page is hidden for agents — use curl with the agent's
`api_access_token`).
3. Expect `401 Unauthorized` with body `{"error":"You are not authorized
to do this action"}`. Repeat for `PATCH` and `DELETE`.
4. Sign in as an administrator and confirm create/edit/delete still work
from Settings → Custom Attributes.
5. As either role, the listing endpoint (`GET
.../custom_attribute_definitions`) should still succeed — agents need
this to render attributes in conversation and contact panels.

Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
2026-05-08 11:42:23 +04:00

53 lines
1.4 KiB
Ruby

class Api::V1::Accounts::CustomAttributeDefinitionsController < Api::V1::Accounts::BaseController
before_action :fetch_custom_attributes_definitions, except: [:create]
before_action :fetch_custom_attribute_definition, only: [:show, :update, :destroy]
before_action :check_authorization
DEFAULT_ATTRIBUTE_MODEL = 'conversation_attribute'.freeze
def index; end
def show; end
def create
@custom_attribute_definition = Current.account.custom_attribute_definitions.create!(
permitted_payload
)
end
def update
@custom_attribute_definition.update!(permitted_payload)
end
def destroy
@custom_attribute_definition.destroy!
head :no_content
end
private
def fetch_custom_attributes_definitions
@custom_attribute_definitions = Current.account.custom_attribute_definitions.with_attribute_model(permitted_params[:attribute_model])
end
def fetch_custom_attribute_definition
@custom_attribute_definition = Current.account.custom_attribute_definitions.find(permitted_params[:id])
end
def permitted_payload
params.require(:custom_attribute_definition).permit(
:attribute_display_name,
:attribute_description,
:attribute_display_type,
:attribute_key,
:attribute_model,
:regex_pattern,
:regex_cue,
attribute_values: []
)
end
def permitted_params
params.permit(:id, :filter_type, :attribute_model)
end
end