Control: 1.2.2 Ensure that an exclusionary Geographic Access Policy is considered
Description
Conditional Access Policies can be used to block access from geographic locations that are deemed out-of-scope for your organization or application. The scope and variables for this policy should be carefully examined and defined.
Conditional Access, when used as a deny list for the tenant or subscription, is able to prevent ingress or egress of traffic to countries that are outside of the scope of interest (e.g.: customers, suppliers) or jurisdiction of an organization. This is an effective way to prevent unnecessary and long-lasting exposure to international threats such as APTs.
Remediation
From Azure Portal
Part 1 of 2 - Create the policy and enable it in Report-only
mode
- From Azure Home open the portal menu in the top left, and select
Azure Active Directory
. - Scroll down in the menu on the left, and select
Security
. - Select on the left side
Conditional Access
. - Click the
+ New policy
button, then: - Under
Assignments
, selectUsers
andGroups
then:- Under
Include
, selectAll users
- Under
Exclude
, only select emergency access accounts and service accounts (NOTE: Service accounts are excluded here because service accounts are non-interactive and cannot complete MFA)
- Under
- Under
Assignments
, selectCloud apps or actions
then:- Under
Include
, selectAll cloud apps
- Leave
Exclude
blank unless you have a well defined exception
- Under
- Under
Conditions:
- Select
Include
, then add entries for locations for those that should be blocked - Select
Exclude
, then add entries for those that should be allowed (IMPORTANT: Ensure that all Trusted Locations are in the Exclude list.)
- Select
- Under
Access Controls
, select Grant and Confirm thatBlock Access
is selected. - Set
Enable policy
toReport-only
and clickCreate
.
NOTE: The policy is not yet 'live,' since Report-only is being used to audit the effect of the policy.
Part 2 of 2 - Confirm that the policy is not blocking access that should be granted, then toggle to On
.
- With your policy now in report-only mode, return to the Azure Active Directoryblade and click on
Sign-ins
. - Review the recent sign-in events - click an event then review the event details (specifically the
Report-only
tab) to ensure:- The sign-in event you're reviewing occurred after turning on the policy in report-only mode
- The policy name from step 4 above is listed in the Policy Name column
- The
Result
column for the new policy shows that the policy wasNot applied
(indicating the location origin was not blocked)
- If the above conditions are present, navigate back to the policy name in Conditional Access and open it.
- Toggle the policy from
Report-only
toOn
.
From PowerShell
First, set up the conditions objects values before updating an existing conditionalaccess policy or before creating a new one. You may need to use additional PowerShell cmdlets to retrieve specific IDs such as the Get-AzureADMSNamedLocationPolicy
which outputs the Location IDs
for use with conditional access policies.
$conditions = New-Object -TypeNameMicrosoft.Open.MSGraph.Model.ConditionalAccessConditionSet$conditions.Applications = New-Object -TypeNameMicrosoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition$conditions.Applications.IncludeApplications = <"All" | "Office365" | "appID" | @("app ID 1", "app ID 2", etc...>$conditions.Applications.ExcludeApplications = <"Office365" | "app ID" |@("app ID 1", "app ID 2", etc...)>$conditions.Users = New-Object -TypeNameMicrosoft.Open.MSGraph.Model.ConditionalAccessUserCondition$conditions.Users.IncludeUsers = <"All" | "None" | "GuestsOrExternalUsers" |"Specific User ID" | @("User ID 1", "User ID 2", etc.)>$conditions.Users.ExcludeUsers = <"GuestsOrExternalUsers" | "Specific UserID" | @("User ID 1", "User ID 2", etc.)>$conditions.Users.IncludeGroups = <"group ID" | "All" | @("Group ID 1","Group ID 2", etc...)>$conditions.Users.ExcludeGroups = <"group ID" | @("Group ID 1", "Group ID 2",etc...)>$conditions.Users.IncludeRoles = <"Role ID" | "All" | @("Role ID 1", "Role ID2", etc...)>$conditions.Users.ExcludeRoles = <"Role ID" | @("Role ID 1", "Role ID 2",etc...)>$conditions.Locations = New-Object -TypeNameMicrosoft.Open.MSGraph.Model.ConditionalAccessLocationCondition$conditions.Locations.IncludeLocations = <"Location ID" | @("Location ID 1","Location ID 2", etc...) >$conditions.Locations.ExcludeLocations = <"AllTrusted" | "Location ID" |@("Location ID 1", "Location ID 2", etc...)>$controls = New-Object -TypeNameMicrosoft.Open.MSGraph.Model.ConditionalAccessGrantControls$controls._Operator = "OR"$controls.BuiltInControls = "block"
Next, update the existing conditional access policy with the condition set options configured with the previous commands.
Set-AzureADMSConditionalAccessPolicy -PolicyId <policy ID> -Conditions $conditions -GrantControls $controls
To create a new conditional access policy that complies with this best practice, run the following commands after creating the condition set above
New-AzureADMSConditionalAccessPolicy -Name "Policy Name" -State <enabled|disabled> - Conditions $conditions -GrantControls $controls
Default Value
This policy does not exist by default.
Usage
Run the control in your terminal:
powerpipe control run azure_compliance.control.cis_v150_1_2_2
Snapshot and share results via Turbot Pipes:
powerpipe loginpowerpipe control run azure_compliance.control.cis_v150_1_2_2 --share
SQL
This control uses a named query:
ad_manual_control