{
  "id": "CB-M365-APPS-002",
  "standard": "m365",
  "version": "main",
  "url": "https://baselines.cirsec.org/b/m365/CB-M365-APPS-002",
  "json": "https://baselines.cirsec.org/b/m365/CB-M365-APPS-002.json",
  "yaml": "https://baselines.cirsec.org/b/m365/CB-M365-APPS-002.yml",
  "profiles_effective": [
    "baseline",
    "hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-M365-APPS-002",
    "title": "Restrict user consent to applications",
    "finding": {
      "title": "Users can grant any application access to organizational data",
      "description": "An attacker can send a consent link for a malicious multitenant application and obtain a token to the victim's mail, files or directory data without ever knowing a password."
    },
    "status": "active",
    "profiles": [
      "baseline"
    ],
    "risk": {
      "severity": "high"
    },
    "assessment": "manual",
    "tags": [
      "applications",
      "consent",
      "illicit-consent",
      "oauth",
      "entra-id"
    ],
    "description": "User consent to applications is limited by the **{{ user_consent }}** level:\n\n- `low-risk`: users can consent only to applications from verified publishers or registered in\n  the tenant, and only for permissions classified as low impact (built-in policy\n  `microsoft-user-default-low`);\n- `none`: users cannot consent to any application; every request goes to an administrator\n  through the admin consent workflow (CB-M365-APPS-005).\n\nThe legacy setting **Allow user consent for apps** (`microsoft-user-default-legacy`) is never\nused.\n",
    "rationale": "Illicit consent grant is a phishing technique that skips the password and MFA entirely: the\nvictim signs in on the real Microsoft page and approves permissions for the attacker's\napplication, which then keeps a refresh token. Limiting consent to verified publishers and\nlow-impact permissions removes most of these lures; removing user consent entirely removes all\nof them.\n",
    "impact": "With `low-risk`, users can still connect common applications that ask only for sign-in and basic\nprofile permissions. Classify the low-impact permissions first (**Permission classifications**),\notherwise the list is empty and every request needs an administrator. With `none`, each new\napplication needs an administrator decision: size the review team before switching.\n",
    "notes": "Existing grants are not removed when the setting changes. Review them under **Enterprise apps** >\n**Permissions** and revoke those that are not needed (CB-M365-APPS-011).\n",
    "setting": {
      "location": "Entra admin center > Entra ID > Enterprise apps > Consent and permissions > User consent settings (Graph authorizationPolicy.defaultUserRolePermissions.permissionGrantPoliciesAssigned)",
      "default_value": "Allow user consent for apps from verified publishers, for selected permissions (Microsoft-managed recommendation in recent tenants)",
      "recommended_value": "{{ user_consent }}"
    },
    "parameters": [
      {
        "name": "user_consent",
        "type": "enum",
        "description": "Highest user consent level allowed. low-risk allows verified publishers and low-impact permissions only; none disables user consent.",
        "allowed": [
          "low-risk",
          "none"
        ],
        "default": "low-risk",
        "profile_defaults": {
          "hardened": "none"
        }
      }
    ],
    "audit": {
      "manual": "1. Sign in to the Microsoft Entra admin center (https://entra.microsoft.com) as at least a\n   Global Reader.\n2. Browse to **Entra ID** > **Enterprise apps** > **Consent and permissions** > **User consent\n   settings**.\n3. Check **User consent for applications**:\n   - for `low-risk`: **Allow user consent for apps from verified publishers, for selected\n     permissions** or **Do not allow user consent**;\n   - for `none`: **Do not allow user consent**.\n4. With `low-risk`, open **Permission classifications** and check that only low-impact\n   delegated permissions (for example `openid`, `profile`, `email`, `offline_access`,\n   `User.Read`) are listed.\n5. Alternative in Microsoft Graph PowerShell (scope `Policy.Read.All`):\n   `(Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions.PermissionGrantPoliciesAssigned`.\n   Entries starting with `ManagePermissionGrantsForSelf.` define user consent:\n   `microsoft-user-default-low` matches `low-risk`; no such entry matches `none`.\n6. Fail if **Allow user consent for apps** is selected (`microsoft-user-default-legacy`), if a\n   custom `ManagePermissionGrantsForSelf.*` policy is broader than low-impact permissions, or if\n   the level is looser than `{{ user_consent }}`.\n"
    },
    "remediation": {
      "manual": "1. Turn on the admin consent workflow first (CB-M365-APPS-005) so that blocked users can ask for\n   access.\n2. Sign in to the Microsoft Entra admin center as at least a Privileged Role Administrator\n   (Global Administrator is required for the portal page).\n3. For `low-risk`, browse to **Entra ID** > **Enterprise apps** > **Consent and permissions** >\n   **Permission classifications** and add the low-impact delegated permissions.\n4. Browse to **User consent settings** and select **Allow user consent for apps from verified\n   publishers, for selected permissions** (`low-risk`) or **Do not allow user consent**\n   (`none`). Select **Save**.\n5. Alternative in Microsoft Graph PowerShell (scope `Policy.ReadWrite.Authorization`): read\n   the current `PermissionGrantPoliciesAssigned`, keep the `ManagePermissionGrantsForOwnedResource.*`\n   entries, and set the `ManagePermissionGrantsForSelf.*` entry to\n   `ManagePermissionGrantsForSelf.microsoft-user-default-low` (or remove it for `none`) with\n   `Update-MgPolicyAuthorizationPolicy`.\n",
      "rollback": "Select the previous consent option. Do not return to **Allow user consent for apps**.\n"
    },
    "references": [
      {
        "title": "Configure how users consent to applications",
        "url": "https://learn.microsoft.com/entra/identity/enterprise-apps/configure-user-consent",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      },
      {
        "title": "Manage app consent policies",
        "url": "https://learn.microsoft.com/entra/identity/enterprise-apps/manage-app-consent-policies",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      },
      {
        "title": "Baseline security mode settings",
        "url": "https://learn.microsoft.com/microsoft-365/baseline-security-mode/baseline-security-mode-settings",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      }
    ],
    "mappings": [
      {
        "framework": "cisa-scuba-m365",
        "framework_version": "2.0.0",
        "id": "MS.AAD.5.2v1",
        "relation": "equivalent"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-6",
        "relation": "related"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "CM-11",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1528"
      },
      {
        "framework": "mitre-attack",
        "id": "T1566"
      }
    ],
    "related_controls": [
      {
        "id": "CB-M365-APPS-001",
        "type": "related"
      },
      {
        "id": "CB-M365-APPS-003",
        "type": "related"
      },
      {
        "id": "CB-M365-APPS-004",
        "type": "related"
      },
      {
        "id": "CB-M365-APPS-005",
        "type": "requires"
      },
      {
        "id": "CB-M365-APPS-011",
        "type": "related"
      },
      {
        "id": "CB-M365-COLLAB-022",
        "type": "related"
      },
      {
        "id": "CB-M365-MAIL-037",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-24",
    "updated": "2026-10-24"
  }
}