Browse Source

Restrict group reads to manage_groups and hide policy contents without manage_policies

Tighten two custom-role read paths that were broader than intended:

- get_group, get_group_details and get_group_members only required
  ManagerHeadersLoose, exposing group metadata, collection mappings and
  membership to any confirmed Manager/Custom member. Require
  ManageGroupsHeaders (Admin/Owner or manage_groups) instead.

- list_policies returned the full policy configuration to any manage_*
  member. Keep the endpoint reachable so the Admin Console still loads,
  but return an empty list to callers without manage_policies.
pull/7397/head
tom27052006 2 weeks ago
parent
commit
02b6c2c205
  1. 39
      src/api/core/organizations.rs

39
src/api/core/organizations.rs

@ -2039,21 +2039,18 @@ async fn list_policies(org_id: OrganizationId, headers: ManagerHeadersLoose, con
err!("Organization not found", "Organization id's do not match"); err!("Organization not found", "Organization id's do not match");
} }
// Security: only Admins/Owners, or Custom members holding at least one management // Security: only Admins/Owners, or Custom members holding the manage_policies permission,
// permission, may read the full policy list (the Admin Console needs it to load). // may see the actual policy configuration. Other Managers/Custom members (e.g. manage_users
// Plain Managers and Custom members without any permission keep the pre-existing // or manage_groups only) are still allowed to call this endpoint so the Admin Console can
// behaviour of having no access here. // load, but they receive an empty list instead of the policy contents.
let membership = &headers.membership; let can_view_policies =
if !(membership.atype >= MembershipType::Admin headers.membership.atype >= MembershipType::Admin || headers.membership.has_manage_policies();
|| membership.has_manage_users()
|| membership.has_manage_groups() let policies_json: Vec<Value> = if can_view_policies {
|| membership.has_manage_policies()) OrgPolicy::find_by_org(&org_id, &conn).await.iter().map(OrgPolicy::to_json).collect()
{ } else {
err!("You don't have permission to view policies") Vec::new()
} };
let policies = OrgPolicy::find_by_org(&org_id, &conn).await;
let policies_json: Vec<Value> = policies.iter().map(OrgPolicy::to_json).collect();
Ok(Json(json!({ Ok(Json(json!({
"data": policies_json, "data": policies_json,
@ -2856,10 +2853,10 @@ async fn add_update_group(
async fn get_group_details( async fn get_group_details(
org_id: OrganizationId, org_id: OrganizationId,
group_id: GroupId, group_id: GroupId,
headers: ManagerHeadersLoose, headers: ManageGroupsHeaders,
conn: DbConn, conn: DbConn,
) -> JsonResult { ) -> JsonResult {
if org_id != headers.membership.org_uuid { if org_id != headers.org_id {
err!("Organization not found", "Organization id's do not match"); err!("Organization not found", "Organization id's do not match");
} }
if !CONFIG.org_groups_enabled() { if !CONFIG.org_groups_enabled() {
@ -2950,10 +2947,10 @@ async fn bulk_delete_groups(
async fn get_group( async fn get_group(
org_id: OrganizationId, org_id: OrganizationId,
group_id: GroupId, group_id: GroupId,
headers: ManagerHeadersLoose, headers: ManageGroupsHeaders,
conn: DbConn, conn: DbConn,
) -> JsonResult { ) -> JsonResult {
if org_id != headers.membership.org_uuid { if org_id != headers.org_id {
err!("Organization not found", "Organization id's do not match"); err!("Organization not found", "Organization id's do not match");
} }
if !CONFIG.org_groups_enabled() { if !CONFIG.org_groups_enabled() {
@ -2971,10 +2968,10 @@ async fn get_group(
async fn get_group_members( async fn get_group_members(
org_id: OrganizationId, org_id: OrganizationId,
group_id: GroupId, group_id: GroupId,
headers: ManagerHeadersLoose, headers: ManageGroupsHeaders,
conn: DbConn, conn: DbConn,
) -> JsonResult { ) -> JsonResult {
if org_id != headers.membership.org_uuid { if org_id != headers.org_id {
err!("Organization not found", "Organization id's do not match"); err!("Organization not found", "Organization id's do not match");
} }
if !CONFIG.org_groups_enabled() { if !CONFIG.org_groups_enabled() {

Loading…
Cancel
Save