diff --git a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
index e42f408a17..86d61b614a 100644
--- a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
+++ b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
@@ -107,10 +107,25 @@ function Export-AADProvider {
# 5.3, 5.4
$DirectorySettings = ConvertTo-Json -Depth 10 @($Tracker.TryCommand("Get-MgBetaDirectorySetting"))
- # Read the properties and relationships of an authentication method policy
- $AuthenticationMethodPolicy = ConvertTo-Json @($Tracker.TryCommand("Get-MgBetaPolicyAuthenticationMethodPolicy")) -Depth 5
+ ##### This block of code below supports 3.3, 3.4, 3.5
+ $AuthenticationMethodPolicyRootObject = $Tracker.TryCommand("Get-MgBetaPolicyAuthenticationMethodPolicy")
- # 6.1
+ $AuthenticationMethodFeatureSettings = @($AuthenticationMethodPolicyRootObject.AuthenticationMethodConfigurations | Where-Object { $_.Id})
+
+ # Exclude the AuthenticationMethodConfigurations so we do not duplicate it in the JSON
+ $AuthenticationMethodPolicy = $AuthenticationMethodPolicyRootObject | ForEach-Object {
+ $_ | Select-Object * -ExcludeProperty AuthenticationMethodConfigurations
+ }
+
+ $AuthenticationMethodObjects = @{
+ authentication_method_policy = $AuthenticationMethodPolicy
+ authentication_method_feature_settings = $AuthenticationMethodFeatureSettings
+ }
+
+ $AuthenticationMethod = ConvertTo-Json -Depth 10 @($AuthenticationMethodObjects)
+ ##### End block
+
+ # 6.1
$DomainSettings = ConvertTo-Json @($Tracker.TryCommand("Get-MgBetaDomain"))
$SuccessfulCommands = ConvertTo-Json @($Tracker.GetSuccessfulCommands())
@@ -125,7 +140,7 @@ function Export-AADProvider {
"privileged_roles": $PrivilegedRoles,
"service_plans": $ServicePlans,
"directory_settings": $DirectorySettings,
- "authentication_method": $AuthenticationMethodPolicy,
+ "authentication_method": $AuthenticationMethod,
"domain_settings": $DomainSettings,
"license_information": $LicenseInfo,
"total_user_count": $UserCount,
@@ -136,6 +151,9 @@ function Export-AADProvider {
$json
}
+ #"authentication_method_policy": $AuthenticationMethodPolicy,
+ #"authentication_method_configuration": $AuthenticationMethodConfiguration,
+ #"authentication_method_feature_settings": $AuthenticationMethodFeatureSettings,
function Get-AADTenantDetail {
<#
.Description
diff --git a/PowerShell/ScubaGear/Rego/AADConfig.rego b/PowerShell/ScubaGear/Rego/AADConfig.rego
index 4bab4bf165..c633cda2f7 100644
--- a/PowerShell/ScubaGear/Rego/AADConfig.rego
+++ b/PowerShell/ScubaGear/Rego/AADConfig.rego
@@ -178,7 +178,7 @@ tests contains {
# If policy matches basic conditions, special conditions,
# all exclusions are intentional, & none but acceptable MFA
# are allowed, save the policy name
-MFAPolicies contains CAPolicy.DisplayName if {
+PhishingResistantMFAPolicies contains CAPolicy.DisplayName if {
some CAPolicy in input.conditional_access_policies
"All" in CAPolicy.Conditions.Users.IncludeUsers
@@ -197,12 +197,12 @@ tests contains {
"PolicyId": "MS.AAD.3.1v1",
"Criticality": "Shall",
"Commandlet": ["Get-MgBetaIdentityConditionalAccessPolicy"],
- "ActualValue": MFAPolicies,
- "ReportDetails": concat(". ", [ReportFullDetailsArray(MFAPolicies, DescriptionString), CAPLINK]),
+ "ActualValue": PhishingResistantMFAPolicies,
+ "ReportDetails": concat(". ", [ReportFullDetailsArray(PhishingResistantMFAPolicies, DescriptionString), CAPLINK]),
"RequirementMet": Status
} if {
DescriptionString := "conditional access policy(s) found that meet(s) all requirements"
- Status := count(MFAPolicies) > 0
+ Status := count(PhishingResistantMFAPolicies) > 0
}
#--
@@ -210,10 +210,10 @@ tests contains {
# MS.AAD.3.2v1
#--
-# Save all policy names if MFAPolicies exist
+# Save all policy names if PhishingResistantMFAPolicies exist
AlternativeMFA contains CAPolicy.DisplayName if {
some CAPolicy in input.conditional_access_policies
- Count(MFAPolicies) > 0
+ Count(PhishingResistantMFAPolicies) > 0
}
# If policy matches basic conditions, special conditions,
@@ -248,55 +248,99 @@ tests contains {
# MS.AAD.3.3v1
#--
-# At this time we are unable to test for X because of NEW POLICY
-# If we have acceptable MFA then policy passes otherwise MS Authenticator need to be
-# enabled to pass. However, we can not currently check if MS Authenticator enabled
-tests contains {
- "PolicyId": "MS.AAD.3.3v1",
- "Criticality": "Shall",
- "Commandlet": ["Get-MgBetaIdentityConditionalAccessPolicy"],
- "ActualValue": MFAPolicies,
- "ReportDetails": concat(". ", [ReportFullDetailsArray(MFAPolicies, DescriptionString), CAPLINK]),
- "RequirementMet": Status
-} if {
- DescriptionString := "conditional access policy(s) found that meet(s) all requirements"
- Status := count(MFAPolicies) > 0
- count(MFAPolicies) > 0
+# Returns the MS Authenticator configuration settings
+MSAuth := auth_setting if {
+ some auth_method in input.authentication_method
+ some auth_setting in auth_method.authentication_method_feature_settings
+
+ auth_setting.Id == "MicrosoftAuthenticator"
+}
+
+# Returns true if MS Authenticator is enabled, false if it is not
+default MSAuthEnabled := false
+MSAuthEnabled := true if {
+ MSAuth.State == "enabled"
}
+# Returns true if MS Authenticator is configured per the baseline, false if it is not
+default MSAuthProperlyConfigured := false
+MSAuthProperlyConfigured := true if {
+ MSAuth.State == "enabled"
+
+ # Make sure that MS Auth shows the app name and geographic location
+ Settings := MSAuth.AdditionalProperties.featureSettings
+ Settings.displayAppInformationRequiredState.state == "enabled"
+ Settings.displayLocationInformationRequiredState.state == "enabled"
+
+ # Make sure that the configuration applies to all users
+ some target in MSAuth.AdditionalProperties.includeTargets
+ target.id == "all_users"
+}
+
+default AAD_3_3_Not_Applicable := false
+# Returns true no matter what if phishing-resistant MFA is being enforced
+AAD_3_3_Not_Applicable := true if {
+ count(PhishingResistantMFAPolicies) > 0
+}
+
+# Returns true if phishing-resistant MFA is not being enforced but MS Auth is disabled
+AAD_3_3_Not_Applicable := true if {
+ count(PhishingResistantMFAPolicies) == 0
+ MSAuthEnabled == false
+}
+
+# First test is for N/A case
tests contains {
"PolicyId": PolicyId,
"Criticality": "Shall/Not-Implemented",
- "Commandlet": [],
+ "Commandlet": ["Get-MgBetaPolicyAuthenticationMethodPolicy"],
"ActualValue": [],
- "ReportDetails": NotCheckedDetails(PolicyId),
+ "ReportDetails": CheckedSkippedDetails(PolicyId, Reason),
"RequirementMet": false
} if {
PolicyId := "MS.AAD.3.3v1"
- count(MFAPolicies) == 0
+ # regal ignore:line-length
+ Reason := "This policy is only applicable if phishing-resistant MFA is not enforced and MS Authenticator is enabled. See %v for more info"
+ AAD_3_3_Not_Applicable == true
+}
+
+# If policy is not N/A then we check that the configuration matches the baseline
+tests contains {
+ "PolicyId": "MS.AAD.3.3v1",
+ "Criticality": "Shall",
+ "Commandlet": ["Get-MgBetaPolicyAuthenticationMethodPolicy"],
+ "ActualValue": MSAuth,
+ "ReportDetails": ReportDetailsBoolean(Status),
+ "RequirementMet": Status
+} if {
+ AAD_3_3_Not_Applicable == false
+
+ Status := MSAuthProperlyConfigured == true
}
-#--
#
# MS.AAD.3.4v1
#--
-PolicyMigrationIsComplete := Status if {
- some Policy in input.authentication_method
- Status := Policy.PolicyMigrationState == "migrationComplete"
+# Returns the auth policy migration state object
+AuthenticationPolicyMigrationState := PolicyMigrationState if {
+ some Setting in input.authentication_method
+ PolicyMigrationState := Setting.authentication_method_policy.PolicyMigrationState
}
-# At this time we are unable to test for X because of NEW POLICY
+# Returns true if the tenant has completed their authpolicy migration
+default AuthenticationPolicyMigrationIsComplete := false
+AuthenticationPolicyMigrationIsComplete if AuthenticationPolicyMigrationState == "migrationComplete"
+
tests contains {
"PolicyId": "MS.AAD.3.4v1",
"Criticality": "Shall",
"Commandlet": ["Get-MgBetaPolicyAuthenticationMethodPolicy"],
- "ActualValue": [Policy.PolicyMigrationState],
+ "ActualValue": [AuthenticationPolicyMigrationState],
"ReportDetails": ReportDetailsBoolean(Status),
"RequirementMet": Status
} if {
- some Policy in input.authentication_method
- Status := Policy.PolicyMigrationState == "migrationComplete"
+ Status := AuthenticationPolicyMigrationIsComplete
}
#--
@@ -304,19 +348,26 @@ tests contains {
# MS.AAD.3.5v1
#--
-GoodAuthenticationMethodConfigurations contains {
+# Returns all the config states for the methods Sms, Voice, Email
+LowSecurityAuthMethods contains {
"Id": Configuration.Id,
"State": Configuration.State
} if {
- some Item in input.authentication_method
- some Configuration in Item.AuthenticationMethodConfigurations
+ some Setting in input.authentication_method
+ some Configuration in Setting.authentication_method_feature_settings
Configuration.Id in ["Sms", "Voice", "Email"]
- Configuration.State == "disabled"
}
+# Returns true only when all the low security auth methods are disabled per the policy
+default LowSecurityAuthMethodsDisabled := false
+LowSecurityAuthMethodsDisabled := true if {
+ every Config in LowSecurityAuthMethods { Config.State == "disabled" }
+}
+
+# First test is for N/A case
tests contains {
"PolicyId": PolicyId,
- "Criticality": "Shall",
+ "Criticality": "Shall/Not-Implemented",
"Commandlet": ["Get-MgBetaPolicyAuthenticationMethodPolicy"],
"ActualValue": [],
"ReportDetails": CheckedSkippedDetails("MS.AAD.3.4v1", Reason),
@@ -325,21 +376,21 @@ tests contains {
PolicyId := "MS.AAD.3.5v1"
# regal ignore:line-length
Reason := "This policy is only applicable if the tenant has their Manage Migration feature set to Migration Complete. See %v for more info"
- PolicyMigrationIsComplete != true
+ AuthenticationPolicyMigrationIsComplete != true
}
+# If policy is not N/A then we check that the configuration matches the baseline
tests contains {
"PolicyId": "MS.AAD.3.5v1",
"Criticality": "Shall",
"Commandlet": ["Get-MgBetaPolicyAuthenticationMethodPolicy"],
- "ActualValue": [],
+ "ActualValue": [LowSecurityAuthMethods],
"ReportDetails": ReportDetailsString(Status, ErrorMessage),
"RequirementMet": Status
} if {
ErrorMessage := "Sms, Voice, and Email authentication must be disabled."
- PolicyMigrationIsComplete == true
- Conditions := [PolicyMigrationIsComplete == true, count(GoodAuthenticationMethodConfigurations) == 3]
- Status := count(FilterArray(Conditions, false)) == 0
+ AuthenticationPolicyMigrationIsComplete == true
+ Status := LowSecurityAuthMethodsDisabled
}
#--
@@ -1148,4 +1199,4 @@ tests contains {
"ReportDetails": NotCheckedDetails("MS.AAD.8.3v1"),
"RequirementMet": false
}
-#--
\ No newline at end of file
+#--
diff --git a/PowerShell/ScubaGear/Testing/Unit/Rego/AAD/AADConfig_03_test.rego b/PowerShell/ScubaGear/Testing/Unit/Rego/AAD/AADConfig_03_test.rego
index 83569a90ca..d81af2c8bb 100644
--- a/PowerShell/ScubaGear/Testing/Unit/Rego/AAD/AADConfig_03_test.rego
+++ b/PowerShell/ScubaGear/Testing/Unit/Rego/AAD/AADConfig_03_test.rego
@@ -1,7 +1,6 @@
package aad_test
import rego.v1
import data.aad
-import data.utils.report.NotCheckedDetails
import data.utils.report.CheckedSkippedDetails
import data.utils.key.TestResult
import data.utils.key.TestResultContains
@@ -1584,7 +1583,7 @@ test_State_Incorrect_V1 if {
#
# Policy MS.AAD.3.3v1
#--
-test_3_1_passes_and_satisfies_3_3 if{
+test_PhishingMFAEnforced_MicrosoftAuthEnabled_NotApplicable if {
Output := aad.tests with input as {
"conditional_access_policies": [
{
@@ -1614,130 +1613,385 @@ test_3_1_passes_and_satisfies_3_3 if{
}
},
"State": "enabled",
- "DisplayName": "Test Policy"
+ "DisplayName": "Phishing Resistant MFA Enforced"
+ }
+ ],
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled"
+ },
+ {
+ "Id": "Email",
+ "State": "enabled"
+ }
+ ]
}
]
}
- ReportDetailStr := concat("", [
- "1 conditional access policy(s) found that meet(s) all requirements:",
- "
Test Policy. View all CA policies."
- ])
-
- TestResult("MS.AAD.3.3v1", Output, ReportDetailStr, true) == true
-}
-
-test_NotImplemented_Correct_V2 if {
PolicyId := "MS.AAD.3.3v1"
-
- Output := aad.tests with input as { }
-
- ReportDetailStr := NotCheckedDetails(PolicyId)
- TestResult(PolicyId, Output, ReportDetailStr, false) == true
+ ReportDetailStr := "This policy is only applicable if phishing-resistant MFA is not enforced and MS Authenticator is enabled. See %v for more info"
+ TestResult(PolicyId, Output, CheckedSkippedDetails(PolicyId, ReportDetailStr), false) == true
}
-#--
-#
-# Policy MS.AAD.3.4v1
-#--
-test_Migrated_Correct if {
+test_PhishingMFAEnforced_MicrosoftAuthDisabled_NotApplicable if {
Output := aad.tests with input as {
+ "conditional_access_policies": [
+ {
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
+ },
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "AuthenticationStrength": {
+ "AllowedCombinations": [
+ "windowsHelloForBusiness",
+ "fido2",
+ "x509CertificateMultiFactor"
+ ]
+ }
+ },
+ "State": "enabled",
+ "DisplayName": "Phishing Resistant MFA Enforced"
+ }
+ ],
"authentication_method": [
{
- "PolicyMigrationState": "migrationComplete"
+ "authentication_method_feature_settings": [
+ {
+ "Id": "MicrosoftAuthenticator",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "enabled"
+ }
+ ]
}
]
}
- TestResult("MS.AAD.3.4v1", Output, PASS, true) == true
+ PolicyId := "MS.AAD.3.3v1"
+ ReportDetailStr := "This policy is only applicable if phishing-resistant MFA is not enforced and MS Authenticator is enabled. See %v for more info"
+ TestResult(PolicyId, Output, CheckedSkippedDetails(PolicyId, ReportDetailStr), false) == true
}
-test_Migrated_Incorrect if {
+test_PhishingMFANotEnforced_MicrosoftAuthDisabled_NotApplicable if {
Output := aad.tests with input as {
+ "conditional_access_policies": [
+ {
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
+ },
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
"authentication_method": [
{
- "PolicyMigrationState": "preMigration"
+ "authentication_method_feature_settings": [
+ {
+ "Id": "MicrosoftAuthenticator",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "enabled"
+ }
+ ]
}
]
}
- TestResult("MS.AAD.3.4v1", Output, FAIL, false) == true
+ PolicyId := "MS.AAD.3.3v1"
+ ReportDetailStr := "This policy is only applicable if phishing-resistant MFA is not enforced and MS Authenticator is enabled. See %v for more info"
+ TestResult(PolicyId, Output, CheckedSkippedDetails(PolicyId, ReportDetailStr), false) == true
}
-#--
-
-#
-# Policy MS.AAD.3.5v1
-#--
-test_NotImplemented_Incorrect_Sms if {
+test_PhishingMFANotEnforced_MicrosoftAuthEnabled_Correct if {
Output := aad.tests with input as {
- "authentication_method": [
+ "conditional_access_policies": [
{
- "PolicyMigrationState": "migrationComplete",
- "AuthenticationMethodConfigurations": [
- {
- "Id": "Sms",
- "State": "enabled"
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
},
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
{
- "Id": "Voice",
- "State": "disabled"
+ "ExcludeTargets": [
+
+ ],
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled",
+ "AdditionalProperties": {
+ "@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration",
+ "isSoftwareOathEnabled": false,
+ "featureSettings": {
+ "displayAppInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ },
+ "displayLocationInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ }
+ },
+ "includeTargets@odata.context": "https://graph.microsoft.com/beta/$metadata#policies/authenticationMethodsPolicy/authenticationMethodConfigurations(\u0027MicrosoftAuthenticator\u0027)/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets",
+ "includeTargets": [
+ {
+ "targetType": "group",
+ "id": "all_users",
+ "isRegistrationRequired": false,
+ "authenticationMode": "any"
+ }
+ ]
+ }
},
{
"Id": "Email",
- "State": "disabled"
+ "State": "enabled"
}
]
}
]
}
- ReportDetails := "Sms, Voice, and Email authentication must be disabled."
- TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+ TestResult("MS.AAD.3.3v1", Output, PASS, true) == true
}
-test_NotImplemented_Incorrect_Voice if {
-
+test_PhishingMFANotEnforced_MicrosoftAuthEnabled_AppnameDisabled_Incorrect if {
Output := aad.tests with input as {
- "authentication_method": [
+ "conditional_access_policies": [
{
- "PolicyMigrationState": "migrationComplete",
- "AuthenticationMethodConfigurations": [
- {
- "Id": "Sms",
- "State": "disabled"
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
},
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
{
- "Id": "Voice",
- "State": "enabled"
+ "ExcludeTargets": [
+
+ ],
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled",
+ "AdditionalProperties": {
+ "@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration",
+ "isSoftwareOathEnabled": false,
+ "featureSettings": {
+ "displayAppInformationRequiredState": {
+ "state": "disabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ },
+ "displayLocationInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ }
+ },
+ "includeTargets@odata.context": "https://graph.microsoft.com/beta/$metadata#policies/authenticationMethodsPolicy/authenticationMethodConfigurations(\u0027MicrosoftAuthenticator\u0027)/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets",
+ "includeTargets": [
+ {
+ "targetType": "group",
+ "id": "all_users",
+ "isRegistrationRequired": false,
+ "authenticationMode": "any"
+ }
+ ]
+ }
},
{
"Id": "Email",
- "State": "disabled"
+ "State": "enabled"
}
]
}
]
}
- ReportDetails := "Sms, Voice, and Email authentication must be disabled."
- TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+ TestResult("MS.AAD.3.3v1", Output, FAIL, false) == true
}
-test_NotImplemented_Incorrect_Email if {
-
+test_PhishingMFANotEnforced_MicrosoftAuthEnabled_GeolocationDisabled_Incorrect if {
Output := aad.tests with input as {
- "authentication_method": [
+ "conditional_access_policies": [
{
- "PolicyMigrationState": "migrationComplete",
- "AuthenticationMethodConfigurations": [
- {
- "Id": "Sms",
- "State": "disabled"
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
},
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
{
- "Id": "Voice",
- "State": "disabled"
+ "ExcludeTargets": [
+
+ ],
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled",
+ "AdditionalProperties": {
+ "@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration",
+ "isSoftwareOathEnabled": false,
+ "featureSettings": {
+ "displayAppInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ },
+ "displayLocationInformationRequiredState": {
+ "state": "disabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ }
+ },
+ "includeTargets@odata.context": "https://graph.microsoft.com/beta/$metadata#policies/authenticationMethodsPolicy/authenticationMethodConfigurations(\u0027MicrosoftAuthenticator\u0027)/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets",
+ "includeTargets": [
+ {
+ "targetType": "group",
+ "id": "all_users",
+ "isRegistrationRequired": false,
+ "authenticationMode": "any"
+ }
+ ]
+ }
},
{
"Id": "Email",
@@ -1748,59 +2002,446 @@ test_NotImplemented_Incorrect_Email if {
]
}
- ReportDetails := "Sms, Voice, and Email authentication must be disabled."
- TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+ TestResult("MS.AAD.3.3v1", Output, FAIL, false) == true
}
-test_NotImplemented_Incorrect_Migration if {
-
+test_PhishingMFANotEnforced_MicrosoftAuthEnabled_AppNameDisabled_GeolocationDisabled_Incorrect if {
Output := aad.tests with input as {
+ "conditional_access_policies": [
+ {
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
+ },
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
"authentication_method": [
{
- "PolicyMigrationState": "preMigration",
- "AuthenticationMethodConfigurations": [
+ "authentication_method_feature_settings": [
+ {
+ "ExcludeTargets": [
+
+ ],
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled",
+ "AdditionalProperties": {
+ "@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration",
+ "isSoftwareOathEnabled": false,
+ "featureSettings": {
+ "displayAppInformationRequiredState": {
+ "state": "disabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ },
+ "displayLocationInformationRequiredState": {
+ "state": "disabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ }
+ },
+ "includeTargets@odata.context": "https://graph.microsoft.com/beta/$metadata#policies/authenticationMethodsPolicy/authenticationMethodConfigurations(\u0027MicrosoftAuthenticator\u0027)/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets",
+ "includeTargets": [
+ {
+ "targetType": "group",
+ "id": "all_users",
+ "isRegistrationRequired": false,
+ "authenticationMode": "any"
+ }
+ ]
+ }
+ },
{
- "Id": "Sms",
+ "Id": "Email",
"State": "enabled"
+ }
+ ]
+ }
+ ]
+ }
+
+ TestResult("MS.AAD.3.3v1", Output, FAIL, false) == true
+}
+
+test_PhishingMFANotEnforced_MicrosoftAuthEnabled_includeTargetsNotAll_Incorrect if {
+ Output := aad.tests with input as {
+ "conditional_access_policies": [
+ {
+ "Conditions": {
+ "Applications": {
+ "IncludeApplications": [
+ "All"
+ ],
+ "ExcludeApplications": []
},
+ "Users": {
+ "IncludeUsers": [
+ "All"
+ ],
+ "ExcludeUsers": [],
+ "ExcludeGroups": [],
+ "ExcludeRoles": []
+ }
+ },
+ "GrantControls": {
+ "BuiltInControls": [
+ "mfa"
+ ]
+ },
+ "State": "enabled",
+ "DisplayName": "Vanilla MFA Enforced - not phishing-resistant"
+ }
+ ],
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
{
- "Id": "Voice",
- "State": "disabled"
+ "ExcludeTargets": [
+
+ ],
+ "Id": "MicrosoftAuthenticator",
+ "State": "enabled",
+ "AdditionalProperties": {
+ "@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration",
+ "isSoftwareOathEnabled": false,
+ "featureSettings": {
+ "displayAppInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ },
+ "displayLocationInformationRequiredState": {
+ "state": "enabled",
+ "includeTarget": {
+ "targetType": "group",
+ "id": "all_users"
+ },
+ "excludeTarget": {
+ "targetType": "group",
+ "id": "00000000-0000-0000-0000-000000000000"
+ }
+ }
+ },
+ "includeTargets@odata.context": "https://graph.microsoft.com/beta/$metadata#policies/authenticationMethodsPolicy/authenticationMethodConfigurations(\u0027MicrosoftAuthenticator\u0027)/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets",
+ "includeTargets": [
+ {
+ "targetType": "group",
+ "id": "not_all_users",
+ "isRegistrationRequired": false,
+ "authenticationMode": "any"
+ }
+ ]
+ }
},
{
"Id": "Email",
- "State": "disabled"
+ "State": "enabled"
}
]
}
]
}
+ TestResult("MS.AAD.3.3v1", Output, FAIL, false) == true
+}
+
+#--
+
+#
+# Policy MS.AAD.3.4v1
+#--
+test_PolicyMigrationState_Correct if {
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ TestResult("MS.AAD.3.4v1", Output, PASS, true) == true
+}
+
+test_PolicyMigrationState_preMigration_Incorrect if {
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_policy": {
+ "PolicyMigrationState": "preMigration"
+ }
+ }
+ ]
+ }
+
+ TestResult("MS.AAD.3.4v1", Output, FAIL, false) == true
+}
+
+test_PolicyMigrationState_migrationInProgress_Incorrect if {
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationInProgress"
+ }
+ }
+ ]
+ }
+
+ TestResult("MS.AAD.3.4v1", Output, FAIL, false) == true
+}
+#--
+
+#
+# Policy MS.AAD.3.5v1
+#--
+test_LowSecurityAuthMethods_SmsEnabled_Incorrect if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "enabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "disabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ ReportDetails := "Sms, Voice, and Email authentication must be disabled."
+ TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+}
+
+test_LowSecurityAuthMethods_VoiceEnabled_Incorrect if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "disabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "enabled"
+ },
+ {
+ "Id": "Email",
+ "State": "disabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ ReportDetails := "Sms, Voice, and Email authentication must be disabled."
+ TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+}
+
+test_LowSecurityAuthMethods_EmailEnabled_Incorrect if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "disabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "enabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ ReportDetails := "Sms, Voice, and Email authentication must be disabled."
+ TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+}
+
+test_LowSecurityAuthMethods_TwoMethodsEnabled_Incorrect if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "enabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "enabled"
+ },
+ {
+ "Id": "Email",
+ "State": "disabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ ReportDetails := "Sms, Voice, and Email authentication must be disabled."
+ TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+}
+
+test_LowSecurityAuthMethods_AllMethodsEnabled_Incorrect if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "enabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "enabled"
+ },
+ {
+ "Id": "Email",
+ "State": "enabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
+ }
+ ]
+ }
+
+ ReportDetails := "Sms, Voice, and Email authentication must be disabled."
+ TestResult("MS.AAD.3.5v1", Output, ReportDetails, false) == true
+}
+
+test_LowSecurityAuthMethods_PreMigration_NotImplemented if {
+
+ Output := aad.tests with input as {
+ "authentication_method": [
+ {
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "enabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "disabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "preMigration"
+ }
+ }
+ ]
+ }
+
# regal ignore:line-length
Reason := "This policy is only applicable if the tenant has their Manage Migration feature set to Migration Complete. See %v for more info"
TestResult("MS.AAD.3.5v1", Output, CheckedSkippedDetails("MS.AAD.3.4v1", Reason), false) == true
}
-test_NotImplemented_Correct_V4 if {
+test_LowSecurityAuthMethods_MigrationComplete_Correct if {
Output := aad.tests with input as {
"authentication_method": [
{
- "PolicyMigrationState": "migrationComplete",
- "AuthenticationMethodConfigurations": [
- {
- "Id": "Sms",
- "State": "disabled"
- },
- {
- "Id": "Voice",
- "State": "disabled"
- },
- {
- "Id": "Email",
- "State": "disabled"
- }
- ]
+ "authentication_method_feature_settings": [
+ {
+ "Id": "Sms",
+ "State": "disabled"
+ },
+ {
+ "Id": "Voice",
+ "State": "disabled"
+ },
+ {
+ "Id": "Email",
+ "State": "disabled"
+ }
+ ],
+
+ "authentication_method_policy": {
+ "PolicyMigrationState": "migrationComplete"
+ }
}
]
}
diff --git a/Testing/Functional/Products/Products.Tests.ps1 b/Testing/Functional/Products/Products.Tests.ps1
index 5629a2f5ef..b96edfd694 100644
--- a/Testing/Functional/Products/Products.Tests.ps1
+++ b/Testing/Functional/Products/Products.Tests.ps1
@@ -284,10 +284,6 @@ Describe "Policy Checks for "{
$Details = $PolicyResultObj.ReportDetails
$Details | Should -Not -BeNullOrEmpty -Because "expect details, $Details"
- if ($IsNotChecked){
- $Details | Should -Match 'This product does not currently have the capability to check compliance for this policy.+'
- }
-
if ($IsCustomImplementation){
$Details | Should -Match 'A custom product can be used to fulfill this policy requirement.+'
}
@@ -360,8 +356,7 @@ Describe "Policy Checks for "{
$RowData[4].text | Should -Match 'A custom product can be used to fulfill this policy requirement.+'
}
elseif ($IsNotChecked){
- $RowData[2].text | Should -BeLikeExactly "N/A" -Because "custom policies should not have results. [$Msg]"
- $RowData[4].text | Should -Match 'This product does not currently have the capability to check compliance for this policy.+'
+ $RowData[2].text | Should -BeLikeExactly "N/A" -Because "policies that are not checked should be N/A. [$Msg]"
}
elseif ($true -eq $ExpectedResult) {
$RowData[2].text | Should -BeLikeExactly "Pass" -Because "expected policy to pass. [$Msg]"
diff --git a/Testing/Functional/Products/TestPlans/aad.testplan.yaml b/Testing/Functional/Products/TestPlans/aad.testplan.yaml
index 61f2ebe36b..524a70a7b0 100644
--- a/Testing/Functional/Products/TestPlans/aad.testplan.yaml
+++ b/Testing/Functional/Products/TestPlans/aad.testplan.yaml
@@ -198,13 +198,102 @@ TestPlan:
ExpectedResult: true
- PolicyId: MS.AAD.3.3v1
- TestDriver: RunScuba
+ TestDriver: RunCached
Tests:
- - TestDescription: MS.AAD.3.3v1 Not Checked
- Preconditions: []
+ - TestDescription: MS.AAD.3.3v1 Not-applicable case - PhishingMFA Enforced MS Auth Enabled
+ Preconditions:
+ - Command: UpdateCachedConditionalAccessPolicyByName
+ Splat:
+ displayName: Automated Test 1 - DO NOT MODIFY
+ updates:
+ State: enabled
+ Conditions:
+ Users:
+ IncludeUsers: ["All"]
+ ExcludeUsers: []
+ IncludeGroups: []
+ ExcludeGroups: []
+ IncludeRoles: []
+ ExcludeRoles: []
+ Applications:
+ IncludeApplications: ["All"]
+ ExcludeApplications: []
+ GrantControls.AuthenticationStrength.AllowedCombinations:
+ - "windowsHelloForBusiness"
+ - "fido2"
+ - "x509CertificateMultiFactor"
+ - Command: UpdateProviderExport
+ Splat:
+ updates:
+ authentication_method[0].authentication_method_feature_settings:
+ - Id: MicrosoftAuthenticator
+ State: enabled
+ AdditionalProperties:
+ featureSettings:
+ displayAppInformationRequiredState:
+ state: disabled
+ displayLocationInformationRequiredState:
+ state: disabled
+ includeTargets:
+ - id: "all_users"
Postconditions: []
IsNotChecked: true
ExpectedResult: false
+ - TestDescription: MS.AAD.3.3v1 Not-applicable case - PhishingMFA Not Enforced MS Auth Disabled
+ Preconditions:
+ - Command: UpdateProviderExport
+ Splat:
+ updates:
+ authentication_method[0].authentication_method_feature_settings:
+ - Id: MicrosoftAuthenticator
+ State: disabled
+ AdditionalProperties:
+ featureSettings:
+ displayAppInformationRequiredState:
+ state: disabled
+ displayLocationInformationRequiredState:
+ state: disabled
+ includeTargets:
+ - id: "all_users"
+ Postconditions: []
+ IsNotChecked: true
+ ExpectedResult: false
+ - TestDescription: MS.AAD.3.3v1 Non-Compliant case - MS Auth App name and Geolocation disabled
+ Preconditions:
+ - Command: UpdateProviderExport
+ Splat:
+ updates:
+ authentication_method[0].authentication_method_feature_settings:
+ - Id: MicrosoftAuthenticator
+ State: enabled
+ AdditionalProperties:
+ featureSettings:
+ displayAppInformationRequiredState:
+ state: disabled
+ displayLocationInformationRequiredState:
+ state: disabled
+ includeTargets:
+ - id: "all_users"
+ Postconditions: []
+ ExpectedResult: false
+ - TestDescription: MS.AAD.3.3v1 Compliant case - MS Auth Configured Correctly
+ Preconditions:
+ - Command: UpdateProviderExport
+ Splat:
+ updates:
+ authentication_method[0].authentication_method_feature_settings:
+ - Id: MicrosoftAuthenticator
+ State: enabled
+ AdditionalProperties:
+ featureSettings:
+ displayAppInformationRequiredState:
+ state: enabled
+ displayLocationInformationRequiredState:
+ state: enabled
+ includeTargets:
+ - id: "all_users"
+ Postconditions: []
+ ExpectedResult: true
- PolicyId: MS.AAD.3.4v1
TestDriver: RunCached
@@ -214,7 +303,7 @@ TestPlan:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: preMigration
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: preMigration
Postconditions: []
ExpectedResult: false
- TestDescription: MS.AAD.3.4v1 Compliant case - Migration complete
@@ -222,28 +311,36 @@ TestPlan:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: migrationComplete
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: migrationComplete
Postconditions: []
ExpectedResult: true
- PolicyId: MS.AAD.3.5v1
TestDriver: RunCached
Tests:
- - TestDescription: MS.AAD.3.5v1 Non-compliant case - preMigration
+ - TestDescription: MS.AAD.3.5v1 Not-applicable case - preMigration but auth methods disabled
Preconditions:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: preMigration
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: preMigration
+ authentication_method[0].authentication_method_feature_settings:
+ - Id: Sms
+ State: disabled
+ - Id: Voice
+ State: disabled
+ - Id: Email
+ State: disabled
Postconditions: []
+ IsNotChecked: true
ExpectedResult: false
- TestDescription: MS.AAD.3.5v1 Non-compliant case - Sms enabled
Preconditions:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: migrationComplete
- authentication_method[0].AuthenticationMethodConfigurations:
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: migrationComplete
+ authentication_method[0].authentication_method_feature_settings:
- Id: Sms
State: enabled
- Id: Voice
@@ -257,8 +354,8 @@ TestPlan:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: migrationComplete
- authentication_method[0].AuthenticationMethodConfigurations:
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: migrationComplete
+ authentication_method[0].authentication_method_feature_settings:
- Id: Sms
State: disabled
- Id: Voice
@@ -272,8 +369,8 @@ TestPlan:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: migrationComplete
- authentication_method[0].AuthenticationMethodConfigurations:
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: migrationComplete
+ authentication_method[0].authentication_method_feature_settings:
- Id: Sms
State: disabled
- Id: Voice
@@ -287,8 +384,8 @@ TestPlan:
- Command: UpdateProviderExport
Splat:
updates:
- authentication_method[0].PolicyMigrationState: migrationComplete
- authentication_method[0].AuthenticationMethodConfigurations:
+ authentication_method[0].authentication_method_policy.PolicyMigrationState: migrationComplete
+ authentication_method[0].authentication_method_feature_settings:
- Id: Sms
State: disabled
- Id: Voice
diff --git a/Testing/RunUnitTests.ps1 b/Testing/RunUnitTests.ps1
index 6c38a1a883..a1cd4e0f59 100644
--- a/Testing/RunUnitTests.ps1
+++ b/Testing/RunUnitTests.ps1
@@ -194,7 +194,7 @@ function Invoke-TestName {
if ($Match){
Write-Output "`nTesting $Test"
- ..\opa_windows_amd64.exe test $RegoPolicyPath .\$($Filename.Fullname) -r $Test $Flag
+ & $OPAExe test $RegoPolicyPath .\$($Filename.Fullname) -r $Test $Flag
}
else{
Write-Warning "`nNOT FOUND: $Test in $Filename"