Skip to content

Commit 71a57df

Browse files
authored
Merge pull request #1057 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 1cc10ef + 29e8e6c commit 71a57df

17 files changed

Lines changed: 1899 additions & 97 deletions

File tree

Config/MaliciousApps.json

Lines changed: 1074 additions & 0 deletions
Large diffs are not rendered by default.

Config/standards.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,8 +1587,8 @@
15871587
"ZTNA21807",
15881588
"ZTNA21810"
15891589
],
1590-
"helpText": "Disables users from being able to consent to applications, except for those specified in the field below",
1591-
"docsDescription": "Requires users to get administrator consent before sharing data with applications. You can preapprove specific applications.",
1590+
"helpText": "Disables users from being able to consent to applications, except for those specified in the field below. This standard conflicts with the \"Allow users to consent to applications with low security risk\" standard; only one of the two should be assigned per tenant.",
1591+
"docsDescription": "Requires users to get administrator consent before sharing data with applications. You can preapprove specific applications. This standard conflicts with the \"Allow users to consent to applications with low security risk\" (OauthConsentLowSec) standard. Enabling both on the same tenant causes a remediation conflict, so only assign one.",
15921592
"executiveText": "Requires administrative approval before employees can grant applications access to company data, preventing unauthorized data sharing and potential security breaches. This protects against malicious applications while allowing approved business tools to function normally.",
15931593
"addedComponent": [
15941594
{
@@ -1609,8 +1609,8 @@
16091609
"name": "standards.OauthConsentLowSec",
16101610
"cat": "Entra (AAD) Standards",
16111611
"tag": ["IntegratedApps"],
1612-
"helpText": "Sets the default oauth consent level so users can consent to applications that have low risks.",
1613-
"docsDescription": "Allows users to consent to applications with low assigned risk.",
1612+
"helpText": "Sets the default oauth consent level so users can consent to applications that have low risks. This standard conflicts with the \"Require admin consent for applications\" standard; only one of the two should be assigned per tenant.",
1613+
"docsDescription": "Allows users to consent to applications with low assigned risk. This standard conflicts with the \"Require admin consent for applications (Prevent OAuth phishing)\" (OauthConsent) standard. Enabling both on the same tenant causes a remediation conflict, so only assign one.",
16141614
"executiveText": "Allows employees to approve low-risk applications without administrative intervention, balancing security with productivity. This provides a middle ground between complete restriction and open access, enabling business agility while maintaining protection against high-risk applications.",
16151615
"label": "Allow users to consent to applications with low security risk (Prevent OAuth phishing. Lower impact, less secure)",
16161616
"impact": "Medium Impact",

Modules/CIPPActivityTriggers/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandard.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ function Push-CIPPStandard {
1111

1212
$Tenant = $Item.Tenant
1313
$Standard = $Item.Standard
14+
15+
# FUTURE USE - ZAC
16+
# Grouped Conditional Access batch: deploy all of a tenant's CA templates in one sequential
17+
# pass. Per-template rerun checks and standard-info context are handled inside the batch
18+
# function, so we bypass the generic per-item dispatch below.
19+
# if ($Item.BatchTemplates) {
20+
# $TemplateCount = @($Item.BatchTemplates).Count
21+
# Write-Information "Received Conditional Access batch for $Tenant with $TemplateCount template(s)."
22+
# Set-CippUserAgentContext -Source 'standard' -TemplateId $Item.TemplateId
23+
# $QueuedTime = if ($Item.QueuedTime) { [int64]$Item.QueuedTime } else { 0 }
24+
# try {
25+
# Invoke-CIPPCATemplateBatch -Tenant $Tenant -Templates $Item.BatchTemplates -QueuedTime $QueuedTime
26+
# Write-Information "Conditional Access batch completed for tenant $Tenant"
27+
# } catch {
28+
# Write-LogMessage -API 'Standards' -tenant $Tenant -message "Error running Conditional Access batch for tenant $Tenant - $($_.Exception.Message)" -sev Error -LogData (Get-CippException -Exception $_)
29+
# Write-Warning "Error running Conditional Access batch for tenant $Tenant - $($_.Exception.Message)"
30+
# throw $_.Exception.Message
31+
# }
32+
# return
33+
# }
34+
1435
$FunctionName = 'Invoke-CIPPStandard{0}' -f $Standard
1536

1637
Write-Information "We'll be running $FunctionName"

Modules/CIPPActivityTriggers/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandardsApplyBatch.ps1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ function Push-CIPPStandardsApplyBatch {
2020
return
2121
}
2222

23+
# FUTURE USE - ZAC
24+
# Group all ConditionalAccessTemplate standards per tenant into a single batch item so
25+
# they deploy sequentially (one activity per tenant) instead of fanning out one activity
26+
# per template. This removes the 429 storm against the ~1 req/s CA write endpoint and the
27+
# duplicate named location / c1-c99 / 1040 races. Non-CA standards pass through unchanged.
28+
# $CAStandards = @($AllStandards | Where-Object { $_.Standard -eq 'ConditionalAccessTemplate' })
29+
# if ($CAStandards.Count -gt 0) {
30+
# $OtherStandards = @($AllStandards | Where-Object { $_.Standard -ne 'ConditionalAccessTemplate' })
31+
# $GroupedCA = foreach ($TenantGroup in ($CAStandards | Group-Object -Property Tenant)) {
32+
# [pscustomobject]@{
33+
# Tenant = $TenantGroup.Name
34+
# Standard = 'ConditionalAccessTemplate'
35+
# FunctionName = 'CIPPStandard'
36+
# QueuedTime = ($TenantGroup.Group | Select-Object -First 1).QueuedTime
37+
# BatchTemplates = @($TenantGroup.Group | ForEach-Object {
38+
# [pscustomobject]@{
39+
# Settings = $_.Settings
40+
# TemplateId = $_.TemplateId
41+
# }
42+
# })
43+
# }
44+
# }
45+
# $AllStandards = @($OtherStandards) + @($GroupedCA)
46+
# Write-Information "Grouped $($CAStandards.Count) Conditional Access template standards into $(@($GroupedCA).Count) per-tenant batch item(s)."
47+
# }
48+
2349
Write-Information "Aggregated $($AllStandards.Count) standards from all tenants: $($AllStandards | ConvertTo-Json -Depth 5 -Compress)"
2450

2551
# Start orchestrator to apply standards

Modules/CIPPAlerts/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ function Get-CIPPAlertHuntressRogueApps {
33
.SYNOPSIS
44
Check for rogue apps in a Tenant
55
.DESCRIPTION
6-
This function checks for rogue apps in the tenant by comparing the service principals in the tenant with a list of known rogue apps provided by Huntress.
6+
This function checks for rogue apps in the tenant by comparing the service principals in the tenant with a list of known rogue apps provided by Huntress and a CIPP collections of appids.
77
.FUNCTIONALITY
88
Entrypoint
99
.LINK
@@ -19,8 +19,23 @@ function Get-CIPPAlertHuntressRogueApps {
1919

2020
try {
2121
$RogueApps = Invoke-RestMethod -Uri 'https://huntresslabs.github.io/rogueapps/rogueapps.json'
22-
$RogueAppFilter = $RogueApps.appId -join "','"
23-
$ServicePrincipals = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$filter=appId in ('$RogueAppFilter')" -tenantid $TenantFilter
22+
$CippRogueApps = (Get-Content -Path (Join-Path $env:CIPPRootPath 'Config\schemaDefinitions.json') | ConvertFrom-Json).applications.appId
23+
$HuntressRogueApps = $RogueApps.appId
24+
$RogueAppIds = @($CippRogueApps) + @($HuntressRogueApps) | Where-Object { $_ } | Select-Object -Unique
25+
$Requests = for ($i = 0; $i -lt $RogueAppIds.Count; $i += 15) {
26+
$Chunk = $RogueAppIds[$i..([Math]::Min($i + 14, $RogueAppIds.Count - 1))]
27+
@{
28+
id = [string]$i
29+
method = 'GET'
30+
url = "servicePrincipals?`$filter=appId in ('$($Chunk -join "','")')"
31+
}
32+
}
33+
$Requests = @($Requests)
34+
35+
$ServicePrincipals = if ($Requests.Count -gt 0) {
36+
$Responses = New-GraphBulkRequest -Requests $Requests -tenantid $TenantFilter
37+
foreach ($Response in $Responses) { $Response.body.value }
38+
}
2439
# If IgnoreDisabledApps is true, filter out disabled service principals
2540
if ($InputValue -eq $true) {
2641
$ServicePrincipals = $ServicePrincipals | Where-Object { $_.accountEnabled -eq $true }

Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPStatsTimer.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ function Start-CIPPStatsTimer {
4848
$driftStandardsCount = Get-CIPPStatsDriftStandardsCount
4949
$mobileEnrollment = Get-CIPPStatsMobileEnrollment
5050

51+
# Feature flags
52+
$FeatureFlags = @{}
53+
Get-CIPPFeatureFlag | Select-Object -Property Id, Enabled | ForEach-Object {
54+
$FeatureFlags[$_.Id] = $_.Enabled
55+
}
56+
5157
$SendingObject = [PSCustomObject]@{
5258
rgid = $env:WEBSITE_SITE_NAME
5359
SetupComplete = $SetupComplete
@@ -77,6 +83,10 @@ function Start-CIPPStatsTimer {
7783
PWPush = $RawExt.PWPush.Enabled
7884
CFZTNA = $RawExt.CFZTNA.Enabled
7985
GitHub = $RawExt.GitHub.Enabled
86+
BestPracticeAnalyser = $FeatureFlags.BestPracticeAnalyser
87+
SuperAdminNG = $FeatureFlags.SuperAdminNG
88+
CopilotAI = $FeatureFlags.CopilotAI
89+
MCPServer = $FeatureFlags.MCPServer
8090
} | ConvertTo-Json
8191

8292
try {

0 commit comments

Comments
 (0)