├── .gitignore ├── .vscode └── _launch.json ├── LICENSE ├── composites ├── composite_AAD_Privileged_SPN.js ├── composite_AzureKeyVault_ReviewCallers.js ├── composite_FunctionsHTTPTriggersAndNet.js ├── composite_WebAppScmIpSecurityRestrictions.js ├── composite_akv_mi_mapping.js ├── composite_datafactorySELECT.js ├── composite_priveEsc.js ├── composite_resolve_alerts.js └── disabled_composite_storage_cloudShellNotLogged.js ├── controlTemplate.js ├── controlTemplateSubProvider.js ├── demo.md ├── dev-guide.md ├── diagnosticSettings.js ├── img └── controlfolder.png ├── manualControl.js ├── package-lock.json ├── package.json ├── pandoc-template.docx ├── plugins ├── createProviderFolders.js ├── main.js ├── nodeSrc │ ├── aadHelpers.js │ ├── aadWhatIf.js │ ├── asb.js │ ├── asb2.js │ ├── asbCat.js │ ├── axioshelpers.js │ ├── azPolicy.js │ ├── batch.js │ ├── confirmDiag.js │ ├── deletetokens.js │ ├── east.js │ ├── evalRes.js │ ├── filterExistingProviders.js │ ├── functionResponseSchema.js │ ├── getEffectiveNSG.js │ ├── getProvider.js │ ├── getToken.js │ ├── globalCounter.js │ ├── graph.js │ ├── grouping3.js │ ├── kubeLoadBalancer.js │ ├── listRoles.js │ ├── listWithoutAzCLI.js │ ├── miGeneral.js │ ├── microsoftwebhelper.js │ ├── nativescope.js │ ├── nodeRestRef.js │ ├── orderValues.js │ ├── query.js │ ├── recursor.js │ ├── reprocess.js │ ├── returnObjectInit.js │ ├── schemaBuilder.js │ ├── subProviderCheck.js │ ├── testConnection.js │ └── webAppConfig.js ├── other │ ├── defaultPolicydef.json │ └── wordlist.json ├── pluginRunner.js └── session │ └── dontremove.json ├── providers ├── ignore.json ├── microsoft.apimanagement │ ├── .apiVersion.json │ ├── controls │ │ ├── APIM_JWTValidation.json │ │ ├── APIM_backEnd-credentials.json │ │ ├── APIM_diagnosticSettings.json │ │ └── listAPI.json │ └── functions │ │ ├── APIM_backEnd-credentials.js │ │ ├── APIM_diagnosticSettings.js │ │ ├── disabled_APIM_JWTValidation.js │ │ └── listAPI.js ├── microsoft.authorization │ ├── .apiVersion.json │ ├── controls │ │ ├── Subscription_amdcAlerts.json │ │ ├── Subscription_scanAuditLogs.json │ │ ├── Subscriptions_ActivityLog.json │ │ ├── Subscriptions_DefenderCoverage.json │ │ ├── Subscriptions_IndirectAccess.json │ │ ├── Subscriptions_PreventSubscriptionTransfer.json │ │ ├── Subscriptions_SecurityContact.json │ │ ├── Subscriptions_classicAdministrators.json │ │ ├── Subscriptions_locks.json │ │ ├── Subscriptions_roleAssignments.json │ │ ├── Subscriptions_roleAssignmentsRG.json │ │ ├── Subscriptions_roleAssignmentsRGAdvanced.json │ │ ├── scanAuditLogs.json │ │ └── sub_classicAdministrators.json │ └── functions │ │ ├── Subscription_amdcAlerts.js │ │ ├── Subscription_scanAuditLogs.js │ │ ├── Subscriptions_ActivityLog.js │ │ ├── Subscriptions_DefenderCoverage.js │ │ ├── Subscriptions_IndirectAccess.js │ │ ├── Subscriptions_PreventSubscriptionTransfer.js │ │ ├── Subscriptions_SecurityContact.js │ │ ├── Subscriptions_classicAdministrators.js │ │ ├── Subscriptions_locks.js │ │ ├── Subscriptions_roleAssignmentsRGAdvanced.js │ │ ├── disabled_Subscriptions_roleAssignments.js │ │ ├── disabled_Subscriptions_roleAssignmentsRG copy.js │ │ ├── disabled_Subscriptions_roleAssignmentsRG.js │ │ ├── disabled_scanAuditLogs.js │ │ └── disabled_sub_classicAdministrators.js ├── microsoft.azureactivedirectory │ ├── .apiVersion.json │ ├── controls │ │ ├── aad_caEval.json │ │ ├── aad_ca_azureDevops.json │ │ ├── aad_counts.json │ │ ├── aad_diagnostics.json │ │ ├── adminsCa.json │ │ ├── basicAuth.json │ │ ├── caPolicies.json │ │ └── consentSettings.json │ └── functions │ │ ├── aad_caEval.js │ │ ├── aad_ca_azureDevops.js │ │ ├── aad_counts.js │ │ ├── aad_diagnostics.js │ │ ├── adminsCa.js │ │ ├── basicAuth.js │ │ ├── caPolicies.js │ │ └── consentSettings.js ├── microsoft.azuredevops │ ├── .apiVersion.json │ ├── controls │ │ ├── azdevops_listPipelines.json │ │ └── azdevops_listServiceEndpoints.json │ └── functions │ │ ├── azdevops_listPipelines.js │ │ └── azdevops_listServiceEndpoints.js ├── microsoft.cdn │ ├── .apiVersion.json │ ├── .skip.json │ ├── controls │ │ ├── cdn_diagnosticSettings.json │ │ ├── cdn_securityHeaders.json │ │ └── cdn_waf.json │ └── functions │ │ ├── cdn_diagnosticSettings.js │ │ ├── cdn_securityHeaders.js │ │ └── cdn_waf.js ├── microsoft.compute │ ├── .apiVersion.json │ ├── .skip.json │ ├── controls │ │ ├── Compute_PolicyGuestConfig.json │ │ ├── VM_Endpoint.json │ │ ├── VM_ManagedIdentity.json │ │ ├── VM_PublicIP.json │ │ └── VM_SSH_linux.json │ └── functions │ │ ├── Compute_PolicyGuestConfig.js │ │ ├── VM_Endpoint.js │ │ ├── VM_ManagedIdentity.js │ │ ├── VM_PublicIP.js │ │ └── VM_SSH_linux.js ├── microsoft.containerregistry │ ├── .apiVersion.json │ ├── controls │ │ ├── acr_DiagnosticSettings.json │ │ ├── acr_adminUser.json │ │ ├── acr_anonymousPull.json │ │ └── acr_fireWall.json │ └── functions │ │ ├── acr_DiagnosticSettings.js │ │ ├── acr_adminUser.js │ │ ├── acr_anonymousPull.js │ │ └── acr_fireWall.js ├── microsoft.containerservice │ ├── .apiVersion.json │ ├── controls │ │ ├── ContainerService_AKSLocalAdmin.json │ │ ├── ContainerService_DiagnosticSettings.json │ │ ├── ContainerService_EphemeralDisk.json │ │ ├── aks_PolicyState.json │ │ ├── aks_apiServer.json │ │ ├── aks_audit_useOfExec.json │ │ ├── aks_getPublicWorkLoads.json │ │ ├── aks_kubenetARPSpoof.json │ │ ├── aks_networkPolicy.json │ │ ├── aks_networking.json │ │ └── pod_security-policyMapping.json │ └── functions │ │ ├── ContainerService_AKSLocalAdmin.js │ │ ├── ContainerService_DiagnosticSettings.js │ │ ├── ContainerService_EphemeralDisk.js │ │ ├── aks_PolicyState.js │ │ ├── aks_apiServer.js │ │ ├── aks_audit_useOfExec.js │ │ ├── aks_getPublicWorkLoads.js │ │ ├── aks_kubenetARPSpoof.js │ │ ├── aks_networkPolicy.js │ │ ├── aks_networking.js │ │ ├── disabled_aks_1getPublicWorkLoads.js │ │ └── pod_security-policyMapping.js ├── microsoft.databricks │ ├── .apiVersion.json │ ├── controls │ │ ├── databricks_auditClustersForNoIsolation.json │ │ ├── databricks_diagnosticSettings.json │ │ └── databricks_skuCheck.json │ └── functions │ │ ├── databricks_auditClustersForNoIsolation.js │ │ ├── databricks_diagnosticSettings.js │ │ └── databricks_skuCheck.js ├── microsoft.datafactory │ ├── .apiVersion.json │ ├── controls │ │ ├── ADF_Linked_Services.json │ │ ├── ADF_diagnosticSettings.json │ │ ├── ADF_pipeLineRuns.json │ │ ├── ADF_pipeline_clearTextVariables.json │ │ └── ADF_pipeline_svc_mapping.json │ └── functions │ │ ├── ADF_Linked_Services.js │ │ ├── ADF_diagnosticSettings.js │ │ ├── ADF_pipeLineRuns.js │ │ ├── ADF_pipeline_clearTextVariables.js │ │ └── ADF_pipeline_svc_mapping.js ├── microsoft.dbformysql │ ├── .apiVersion.json │ ├── controls │ │ ├── mysql_TLSversionEnforcement.json │ │ ├── mysql_firewall.json │ │ └── mysql_sslEnforceMent.json │ └── functions │ │ ├── mysql_TLSversionEnforcement.js │ │ ├── mysql_firewall.js │ │ └── mysql_sslEnforceMent.js ├── microsoft.dbforpostgresql │ ├── .apiVersion.json │ ├── .skip.json │ ├── controls │ │ ├── psql_TLSVersionEnforcement.json │ │ ├── psql_diagnosticSettings.json │ │ ├── psql_fireWall.json │ │ └── psql_sslEnforcement.json │ └── functions │ │ ├── psql_TLSVersionEnforcement.js │ │ ├── psql_diagnosticSettings.js │ │ ├── psql_fireWall.js │ │ └── psql_sslEnforcement.js ├── microsoft.devices │ ├── .apiVersion.json │ ├── controls │ │ ├── EnforceX509.json │ │ ├── IOT_DisableLocalAuth.json │ │ ├── IOT_Firewall.json │ │ └── IOT_diagnosticSettings.json │ └── functions │ │ ├── EnforceX509.js │ │ ├── IOT_DisableLocalAuth.js │ │ ├── IOT_Firewall.js │ │ └── IOT_diagnosticSettings.js ├── microsoft.documentdb │ ├── .apiVersion.json │ ├── controls │ │ └── Microsoft.DocumentDb_Firewall.json │ └── functions │ │ └── Microsoft.DocumentDb_Firewall.js ├── microsoft.eventhub │ ├── .apiVersion.json │ ├── controls │ │ ├── eh_avoidNamespacePolicies.json │ │ ├── eh_diagnosticSettings.json │ │ ├── eh_disableLocalAuth.json │ │ ├── eh_firewall.json │ │ └── eh_useAzureRBACforDataAccess.json │ └── functions │ │ ├── eh_avoidNamespacePolicies.js │ │ ├── eh_diagnosticSettings.js │ │ ├── eh_disableLocalAuth.js │ │ ├── eh_firewall.js │ │ └── eh_useAzureRBACforDataAccess.js ├── microsoft.general │ ├── .apiVersion.json │ ├── controls │ │ ├── general_aad_combined.json │ │ ├── general_aadauthnz.json │ │ └── general_auditLogs.json │ └── functions │ │ ├── general_aad_combined.js │ │ ├── general_aadauthnz.js │ │ └── general_auditLogs.js ├── microsoft.keyvault │ ├── .apiVersion.json │ ├── controls │ │ ├── KeyVault_AdvancedCheck.json │ │ ├── KeyVault_Firewall.json │ │ ├── KeyVault_ReviewListOfCallers.json │ │ ├── KeyVault_accessPolicies.json │ │ ├── Keyvault_ReviewAdvancedAccessPolicies.json │ │ └── keyVault_diagnosticSettings.json │ └── functions │ │ ├── KeyVault_Firewall.js │ │ ├── KeyVault_accessPolicies.js │ │ ├── Keyvault_ReviewAdvancedAccessPolicies.js │ │ ├── disabled_KeyVault_ReviewListOfCallers.js │ │ └── keyVault_diagnosticSettings.js ├── microsoft.logic │ ├── .apiVersion.json │ ├── controls │ │ ├── LogicApps_ActionsAuth.json │ │ ├── LogicApps_Authorization.json │ │ ├── LogicApps_ConnectionAuth.json │ │ ├── LogicApps_ContentRestrictions.json │ │ ├── LogicApps_InBoundRestrictions.json │ │ ├── LogicApps_ManagedIdentity.json │ │ ├── LogicApps_WorkFlows.json │ │ ├── LogicApps_diagnosticSettings.json │ │ └── LogicApps_runHistory.json │ └── functions │ │ ├── LogicApps_ActionsAuth.js │ │ ├── LogicApps_Authorization.js │ │ ├── LogicApps_ConnectionAuth.js │ │ ├── LogicApps_ContentRestrictions.js │ │ ├── LogicApps_InBoundRestrictions.js │ │ ├── LogicApps_ManagedIdentity.js │ │ ├── LogicApps_WorkFlows.js │ │ ├── LogicApps_diagnosticSettings.js │ │ └── LogicApps_runHistory.js ├── microsoft.network │ ├── .apiVersion.json │ ├── .skip.json │ ├── applicationgateways │ │ ├── .apiVersion.json │ │ ├── controls │ │ │ └── agw_waf.json │ │ └── functions │ │ │ └── agw_waf.js │ ├── controls │ │ ├── pip_appliedNSG.json │ │ └── pip_conf_old.json │ ├── frontdoors │ │ ├── .apiVersion.json │ │ ├── controls │ │ │ ├── afd_waf.json │ │ │ └── afd_waf_mode.json │ │ └── functions │ │ │ ├── afd_waf.js │ │ │ └── afd_waf_mode.js │ ├── functions │ │ ├── disabled_pip_appliedNSG.js │ │ └── disabled_pip_conf_old.js │ ├── publicipaddresses │ │ ├── .apiVersion.json │ │ ├── controls │ │ │ └── pip_conf.json │ │ └── functions │ │ │ └── pip_conf.js │ └── virtualnetworks │ │ ├── .apiVersion.json │ │ ├── controls │ │ └── vnet_peerings.json │ │ └── functions │ │ └── vnet_peerings.js ├── microsoft.relay │ ├── .apiVersion.json │ ├── controls │ │ ├── relay_diagnosticSettings.json │ │ ├── relay_hybridConnFirewall.json │ │ └── relay_reviewConnectionEndpoints.json │ ├── functions │ │ ├── relay_diagnosticSettings.js │ │ ├── relay_hybridConnFirewall.js │ │ └── relay_reviewConnectionEndpoints.js │ └── namespaces │ │ ├── .apiVersion.json │ │ ├── controls │ │ ├── relay_diagnosticSettings.json │ │ ├── relay_hybridConnFirewall.json │ │ ├── relay_new.json │ │ └── relay_reviewConnectionEndpoints.json │ │ └── functions │ │ ├── relay_diagnosticSettings.js │ │ ├── relay_hybridConnFirewall.js │ │ ├── relay_new.js │ │ └── relay_reviewConnectionEndpoints.js ├── microsoft.servicebus │ ├── .apiVersion.json │ ├── controls │ │ ├── sb_avoidNamespacePolicies.json │ │ ├── sb_diagnosticSettings.json │ │ ├── sb_disableLocalAuth.json │ │ ├── sb_firewall.json │ │ └── sb_useAzureRBACforDataAccess.json │ └── functions │ │ ├── sb_avoidNamespacePolicies.js │ │ ├── sb_diagnosticSettings.js │ │ ├── sb_disableLocalAuth.js │ │ ├── sb_firewall.js │ │ └── sb_useAzureRBACforDataAccess.js ├── microsoft.servicefabric │ ├── .apiVersion.json │ ├── controls │ │ └── sf_ClusterProtectionLevel.json │ └── functions │ │ └── sf_ClusterProtectionLevel.js ├── microsoft.sql │ ├── .apiVersion.json │ ├── controls │ │ ├── sql_Firewall.json │ │ ├── sql_adminQuery.json │ │ ├── sql_listDatabases.json │ │ ├── sql_minTLS.json │ │ ├── sql_pe.json │ │ └── sql_vulnAssessment.json │ └── functions │ │ ├── disabled_sql_adminQuery.js │ │ ├── disabled_sql_listDatabases.js │ │ ├── sql_Firewall.js │ │ ├── sql_minTLS.js │ │ ├── sql_pe.js │ │ └── sql_vulnAssessment.js ├── microsoft.storage │ ├── .apiVersion.json │ ├── controls │ │ ├── Storage_BlobDiagnostics.json │ │ ├── Storage_ClosePublicIfPE.json │ │ ├── Storage_EnableFirewall.json │ │ ├── Storage_PublicAccess.json │ │ ├── Storage_hasPublicBlobs.json │ │ ├── Storage_httpsOnly.json │ │ ├── storage_aadAuth.json │ │ ├── storage_cloudShell.json │ │ ├── storage_crossTenantReplication.json │ │ ├── storage_denyKeyBasedAuthentication.json │ │ └── storage_denyPublicAccessSetting.json │ └── functions │ │ ├── Storage_BlobDiagnostics.js │ │ ├── Storage_ClosePublicIfPE.js │ │ ├── Storage_EnableFirewall.js │ │ ├── Storage_PublicAccess.js │ │ ├── Storage_hasPublicBlobs.js │ │ ├── Storage_httpsOnly.js │ │ ├── storage_aadAuth.js │ │ ├── storage_cloudShell.js │ │ ├── storage_crossTenantReplication.js │ │ ├── storage_denyKeyBasedAuthentication.js │ │ └── storage_denyPublicAccessSetting.js └── microsoft.web │ ├── .apiVersion.json │ ├── .skip.json │ ├── connections │ ├── .apiVersion.json │ ├── controls │ │ └── LogicApps_Connections.json │ └── functions │ │ └── LogicApps_Connections.js │ ├── controls │ ├── WebApp_LogicAppsWorkflows.json │ ├── WebApp_VnetRouteAll.json │ ├── WebApp_minTLS.json │ ├── WebSites_DiagnosticSettings.json │ ├── Webapp_SCM_admin.json │ ├── aadAuth.json │ ├── fn_runtimeVersion.json │ ├── httpsSettings.json │ ├── listFunctions.json │ ├── managedIdentity.json │ ├── networkRestrictions.json │ ├── remoteDebugging.json │ └── webApp_ftpStatus.json │ └── functions │ ├── WebApp_LogicAppsWorkflows.js │ ├── WebApp_VnetRouteAll.js │ ├── WebApp_minTLS.js │ ├── WebSites_DiagnosticSettings.js │ ├── Webapp_SCM_admin.js │ ├── aadAuth.js │ ├── fn_runtimeVersion.js │ ├── httpsSettings.js │ ├── listFunctions.js │ ├── managedIdentity.js │ ├── networkRestrictions.js │ ├── remoteDebugging.js │ └── webApp_ftpStatus.js ├── readme.md ├── sh ├── deleteToken.sh ├── initControl.sh ├── initForCustomer2.sh ├── initForuse.sh └── updatePolicyDef.sh └── templatehelpers ├── custom ├── _AADDefaultSettings.js ├── _AAD_Privileged_SPN.js ├── _ADF_Linked_Services.js ├── _ADF_pipeline_svc_mapping.js ├── _Subscriptions_roleAssignmentsRGAdvanced.js ├── _aad_caEval.js ├── _adminsCa.js ├── _aks_PolicyState.js └── _sql_vulnAssessment.js └── eastReports.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | md/conversions/** 3 | test.js 4 | #Exclude all log files 5 | *.LOG 6 | *.txt 7 | *.json 8 | *.JSON 9 | *.pdf 10 | # exclude from JSON and MD flag 11 | !_launch.json 12 | !/providers/** 13 | !/azskver/demodata/** 14 | *.md 15 | !east.md 16 | !gitCheat.md 17 | !demo.md 18 | !readme.md 19 | !dev-guide.md 20 | !package* 21 | !plugins/session/dontremove.json 22 | !wordlist.json 23 | !defaultPolicydef.json 24 | # Exlcude all docx files 25 | *.docx 26 | !pandoc-template-horizontal.docx 27 | !pandoc-template.docx 28 | !prepend.docx 29 | 30 | -------------------------------------------------------------------------------- /.vscode/_launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. muutos 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "pwa-node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/plugins/main.js", 15 | // "program": "${file}", 16 | "args": [ 17 | "--batch=10", 18 | //"--tag=svc=aksdev", 19 | "--nativescope=true", 20 | "--roleAssignments", 21 | "--checkAad", 22 | // "--helperTexts", 23 | /* "--subInclude=6193053b-408b-44d0-b20f-4e29b9b67394", */ 24 | //"--namespace=diagsettings", 25 | /* "--notIncludes=storage", */ 26 | //"--policy", 27 | "--nx", 28 | "--asb", 29 | "--scanAuditLogs", 30 | "--composites", 31 | "--clearTokens", 32 | //"--azdevops=thx138", 33 | // "--ignorePreCheck", 34 | /* "--reprocess", */ 35 | "--SkipStorageThrottling", 36 | "--includeRG" 37 | ] 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Joosua Santasalo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /composites/composite_AAD_Privileged_SPN.js: -------------------------------------------------------------------------------- 1 | 2 | // Creates a new map, no need to push the results 3 | 4 | 5 | /* sd(require('../content.json')) 6 | */ 7 | async function sd (src) { 8 | 9 | 10 | let spn = src.find(s => s.controlId == "adminsCa" ) 11 | 12 | var sd =new newObjectCreater(spn) 13 | sd.isHealthy = true 14 | let spns = [] 15 | sd.metadata.results.map(s => s.value.filter(s => s.object.match('servicePrincipal')).map(s => spns.push(`${s.role} - ${s.object}`)) ) 16 | sd.controlId = "AAD_Privileged_SPN" 17 | sd.Description = "Ensure Service Principals are not in privilged Azure AD roles unless justified" 18 | sd.metadata = spns 19 | 20 | 21 | 22 | return sd 23 | } 24 | 25 | 26 | module.exports = async function (src) { 27 | 28 | 29 | let spn = src.find(s => s.controlId == "adminsCa" ) 30 | 31 | if (!spn) { 32 | return; 33 | } 34 | var sd =new newObjectCreater(spn) 35 | sd.isHealthy = true 36 | let spns = [] 37 | sd.metadata.results.map(s => s.value.filter(s => s.object.match('servicePrincipal')).map(s => spns.push(`${s.role} - ${s.object}`)) ) 38 | sd.controlId = "AAD_SPNInAADRole" 39 | sd.Description = "Ensure Service Principals are not in privilged Azure AD roles unless justified" 40 | sd.metadata = spns 41 | 42 | if (spns.length > 0) { 43 | sd.isHealthy ="review" 44 | } 45 | 46 | return sd 47 | } 48 | 49 | function newObjectCreater (data) { 50 | this.data={} 51 | Object.keys(data).map(f => this.data[f] = data[f]) 52 | return this.data 53 | } 54 | 55 | -------------------------------------------------------------------------------- /composites/composite_WebAppScmIpSecurityRestrictions.js: -------------------------------------------------------------------------------- 1 | 2 | // Creates a new map, no need to push the results 3 | 4 | module.exports = async function (src) { 5 | 6 | 7 | const processed = src.filter(s => s.controlId == "networkRestrictions" ) 8 | //let s = new responseSchema(item, {Category:"Protection",Description:"Review MDC alerts on this resource"}) 9 | 10 | 11 | let returnable = [] 12 | processed.forEach( sds => { 13 | var sd =new newObjectCreater(sds) 14 | 15 | if (JSON.stringify(sd?.metadata?.scmIpSecurityRestrictions).match('Allow all access')) { 16 | sd.isHealthy = false 17 | } else { 18 | sd.isHealthy = true 19 | } 20 | 21 | 22 | sd.controlId = "composite_WebAppScmIpSecurityRestrictions" 23 | sd.Description = "Review WebApps SCM endpoint restrictions \r\n" 24 | returnable.push(sd) 25 | 26 | } ) 27 | 28 | 29 | return returnable 30 | } 31 | 32 | function newObjectCreater (data) { 33 | this.data={} 34 | Object.keys(data).map(f => this.data[f] = data[f]) 35 | return this.data 36 | } 37 | 38 | -------------------------------------------------------------------------------- /composites/composite_datafactorySELECT.js: -------------------------------------------------------------------------------- 1 | 2 | // Creates a new map, no need to push the results 3 | 4 | module.exports = async function (src) { 5 | 6 | 7 | const processed = src.filter(s => s.controlId == "ADF_pipeLineRuns" ) 8 | const old = src.filter(s => s.controlId == "ADF_pipeLineRuns" ) 9 | //let s = new responseSchema(item, {Category:"Protection",Description:"Review MDC alerts on this resource"}) 10 | 11 | 12 | let returnable = [] 13 | processed.forEach( sds => { 14 | 15 | var sd =new newObjectCreater(sds) 16 | sd.isHealthy = true 17 | 18 | try { 19 | if (sd.metadata?.sqlInput.toLowerCase().match('select')) { 20 | sd.isHealthy = "review" 21 | } 22 | } catch (error) { 23 | console.log('not applicable for SQL statements') 24 | } 25 | 26 | /* 27 | delete sd.metadata.matchLikelySecrets 28 | delete sd.metadata.returnPw */ 29 | console.log(old) 30 | sd.controlId = "composite_ADF_reviewSelectStatements" 31 | sd.Description = "Review pipelines activities with select statements for dynamic and user modifiable input" 32 | returnable.push(sd) 33 | 34 | } ) 35 | 36 | 37 | return returnable 38 | } 39 | 40 | function newObjectCreater (data) { 41 | this.data={} 42 | Object.keys(data).map(f => this.data[f] = data[f]) 43 | return this.data 44 | } 45 | 46 | -------------------------------------------------------------------------------- /composites/disabled_composite_storage_cloudShellNotLogged.js: -------------------------------------------------------------------------------- 1 | 2 | // Creates a new map, no need to push the results 3 | 4 | module.exports = async function (src) { 5 | 6 | 7 | let processed = src.filter(s => s.controlId == "storage_cloudShell" ) 8 | let composite = src.filter(s => s.controlId == "ADF_pipeLineRuns" ) 9 | //let s = new responseSchema(item, {Category:"Protection",Description:"Review MDC alerts on this resource"}) 10 | 11 | 12 | let returnable = [] 13 | processed.map( sd => { 14 | 15 | let missingAuditLogs = "" 16 | 17 | sd.Description = "missed" 18 | //returnable.push(sd) 19 | 20 | } ) 21 | 22 | 23 | return; 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo.md: -------------------------------------------------------------------------------- 1 | ## Demo runs 2 | 3 | ### Full check 4 | ```shell 5 | 6 | node ./plugins/main.js --batch=10 --nativescope=true --roleAssignments=true --helperTexts=true --checkAad=true --scanAuditLogs --composites --shuffle --clearTokens --azdevops=thx138 7 | 8 | 9 | ``` 10 | 11 | ### Single service 12 | ```shell 13 | node ./plugins/main.js --batch=10 --nativescope=true --roleAssignments=true --checkAad=false --namespace="microsoft.datafactory" --helperTexts=true 14 | ``` 15 | 16 | ### Create Templates 17 | 18 | `` node templatehelpers/east.js `` 19 | 20 | - Review deep dive areas 21 | - SPN with password 22 | - Gaps CA 23 | - SPN with directory role 24 | 25 | `` node templatehelpers/functionsWithVault.js`` 26 | 27 | ### Speedup Demo 28 | 29 | ``` 30 | # real 2m40.555s 31 | time node ./plugins/main.js --batch=2 --nativescope=true --roleAssignments=true --helperTexts=true --checkAad=true --scanAuditLogs --composites 32 | 33 | ``` 34 | 35 | ``` 36 | real 1m20.207s 37 | time node ./plugins/main.js --batch=10 --nativescope=true --roleAssignments=true --helperTexts=true --checkAad=true --scanAuditLogs --composites 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /img/controlfolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsa2/EAST/89d94a1bcae1880a583acef5ad249dbc2e226e25/img/controlfolder.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kv.md", 3 | "version": "1.0.0", 4 | "main": "main.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "", 10 | "license": "ISC", 11 | "description": "", 12 | "dependencies": { 13 | "axios": "^1", 14 | "chalk": "^4.1.2", 15 | "js-beautify": "^1.14.7", 16 | "jsonwebtoken": "^9.0.0", 17 | "uuid": "^9", 18 | "yargs": "^17.7.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pandoc-template.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsa2/EAST/89d94a1bcae1880a583acef5ad249dbc2e226e25/pandoc-template.docx -------------------------------------------------------------------------------- /plugins/createProviderFolders.js: -------------------------------------------------------------------------------- 1 | const {exec} =require('child_process') 2 | const fs = require('fs') 3 | const wexc = require('util').promisify(exec) 4 | const path = require('path') 5 | 6 | 7 | main(`az provider list -o tsv --query [].id -o json`) 8 | 9 | async function main (script) { 10 | var {stdout} = await wexc(script) 11 | schemaPayload = JSON.parse(stdout) 12 | 13 | schemaPayload.forEach((item) => { 14 | var folderName = checkForControlId(item) 15 | console.log(folderName) 16 | try {fs.mkdirSync(folderName)} catch (error) { 17 | 'exist' 18 | } 19 | 20 | 21 | }) 22 | 23 | } 24 | 25 | function checkForControlId (id) { 26 | //maximum relativenes to find correct index of Azure ResourceID 27 | var checkId = id.split('/') 28 | var position = checkId.indexOf('providers') 29 | //var position = id.indexOf('providers') 30 | var EASTMap =`${checkId[position]}/${checkId[position+1]}/` 31 | var folder =path.resolve('md/ms/Azure',EASTMap) 32 | console.log(EASTMap) 33 | return folder 34 | 35 | } 36 | -------------------------------------------------------------------------------- /plugins/nodeSrc/axioshelpers.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios') 2 | const qs = require('querystring') 3 | 4 | async function axiosClient (options, urlencoded, debug) { 5 | 6 | if (urlencoded == true) { 7 | options.data = qs.stringify(options.data) 8 | } 9 | if (debug) { 10 | console.log(options) 11 | } 12 | 13 | var data = await axios(options).catch((error) => { 14 | /* console.log(error?.Error) */ 15 | return Promise.reject(error?.response?.data || error?.response?.status || error?.message) 16 | 17 | }) 18 | 19 | return data?.data || data.status 20 | 21 | } 22 | 23 | module.exports = {axiosClient} -------------------------------------------------------------------------------- /plugins/nodeSrc/confirmDiag.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("./east"); 2 | 3 | 4 | async function diagReview (item,categories,requireAll) { 5 | 6 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 7 | 8 | let isOK = false 9 | let results = categories.map(key => { 10 | let subR = { 11 | key, 12 | isEnabled:diagnostics?.value.find(v => v?.properties?.logs.find(log => (log?.category == key || log.categoryGroup == key) && log?.enabled == true)) || "failCheck" 13 | } 14 | 15 | if (subR.isEnabled.toString().length > 10 && isOK ==false ) { 16 | isOK=true 17 | } 18 | 19 | return subR 20 | 21 | }) 22 | 23 | 24 | 25 | 26 | if (requireAll) { 27 | if (JSON.stringify(results).match('failCheck')) { 28 | isOK=false 29 | } 30 | } 31 | 32 | results.isHealthy=isOK 33 | return results 34 | } 35 | 36 | module.exports={diagReview} 37 | 38 | 39 | -------------------------------------------------------------------------------- /plugins/nodeSrc/deletetokens.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | function clearEASTTokenCache() { 4 | 5 | fs.readdirSync('./plugins/session').filter(s => s !== "dontremove.json").map(d => fs.unlinkSync(`./plugins/session/${d}`)) 6 | return; 7 | } 8 | 9 | module.exports= {clearEASTTokenCache} -------------------------------------------------------------------------------- /plugins/nodeSrc/evalRes.js: -------------------------------------------------------------------------------- 1 | 2 | function evalRes() { 3 | 4 | if (!evalRes) { 5 | var evalRes = [] 6 | return evalRes 7 | } else {return evalRes} 8 | } 9 | 10 | module.exports={evalRes} 11 | -------------------------------------------------------------------------------- /plugins/nodeSrc/filterExistingProviders.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | function filterProviders (res) { 5 | 6 | var providersPath = path.resolve(`providers`) 7 | let listF =fs.readdirSync(`${providersPath}`).filter((item) => !item.match('disabled_')) 8 | 9 | let supported =res.filter(item => { 10 | let provider =item.id.split('providers')[1].split('/')[1] 11 | if (listF.includes(provider)) { 12 | return item 13 | } 14 | else { 15 | console.log('skipping', provider) 16 | } 17 | }) 18 | 19 | return supported 20 | 21 | 22 | 23 | 24 | 25 | } 26 | 27 | module.exports={filterProviders} 28 | -------------------------------------------------------------------------------- /plugins/nodeSrc/getProvider.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | 3 | function getProviderApiVersion (item) { 4 | var provider = item.split('providers')[1].split('/')[1] 5 | var providersPath = path.resolve(`providers/${provider}/.apiVersion.json`) 6 | return require(providersPath) 7 | } 8 | 9 | module.exports={getProviderApiVersion} -------------------------------------------------------------------------------- /plugins/nodeSrc/globalCounter.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function globalCounter (i) { 4 | if (i) { 5 | i++; 6 | console.log(i) 7 | } else { 8 | var i = 0 9 | } 10 | 11 | } 12 | 13 | module.exports={globalCounter} -------------------------------------------------------------------------------- /plugins/nodeSrc/kubeLoadBalancer.js: -------------------------------------------------------------------------------- 1 | async function getKubeFrontend () { 2 | 3 | } -------------------------------------------------------------------------------- /plugins/nodeSrc/listRoles.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("./east") 2 | 3 | 4 | // declare existing ahead of time, so if it's required later it will be in memory 5 | var existingRoleDef = [] 6 | 7 | async function checkRoles (sb) { 8 | if (!sb?.id) { 9 | console.log() 10 | } 11 | var opt = { 12 | url:`https://management.azure.com/subscriptions/${sb.id|| sb}/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01&` 13 | } 14 | var results = existingRoleDef.find((item) => { 15 | // console.log(item.sb) 16 | return item.sb == sb 17 | } 18 | ) 19 | if ( !results ) { 20 | 21 | var roles = await AzNodeRest(undefined,undefined,undefined,opt) 22 | var addTo ={ 23 | sb, 24 | roles:roles?.value 25 | } 26 | existingRoleDef.push(addTo) 27 | //console.log('pushed', sb) 28 | return addTo 29 | } else { 30 | return results 31 | } 32 | 33 | 34 | 35 | } 36 | 37 | module.exports={checkRoles} 38 | -------------------------------------------------------------------------------- /plugins/nodeSrc/listWithoutAzCLI.js: -------------------------------------------------------------------------------- 1 | const { getToken } = require("./getToken") 2 | const {argv} = require('yargs') 3 | const { default: axios } = require("axios") 4 | 5 | async function listWithoutAzCLI () { 6 | 7 | try { 8 | 9 | let token = await getToken() 10 | 11 | let subs = argv.subInclude.split(',') 12 | 13 | let r = [] 14 | subs.map(sub => { 15 | 16 | let options = { 17 | url: `https://management.azure.com/subscriptions/${sub}/resources?api-version=2021-04-01`, 18 | headers: { 19 | authorization: `Bearer ${token}` 20 | } 21 | } 22 | 23 | r.push(subListing(options)) 24 | 25 | }) 26 | 27 | let resources = await Promise.all(r) 28 | 29 | 30 | resources = resources.flat().map((rs) => { 31 | 32 | return { 33 | id: rs.id, 34 | name:rs.name 35 | } 36 | }) 37 | 38 | return resources 39 | } catch (error) { 40 | console.log('resource listing failed'); 41 | return undefined 42 | } 43 | 44 | 45 | } 46 | 47 | 48 | async function subListing (options) { 49 | 50 | let {data} = await axios(options) 51 | 52 | return data?.value 53 | 54 | } 55 | 56 | module.exports={listWithoutAzCLI} -------------------------------------------------------------------------------- /plugins/nodeSrc/recursor.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | var items = require('../../content.json') */ 4 | //var item = {} 5 | function makeSingleArray (item,arr) { 6 | if (Array.isArray(item)) { 7 | console.log(item.length) 8 | item.forEach((item) => { 9 | makeSingleArray(item,arr) 10 | }) 11 | } else { 12 | arr.push(item) 13 | } 14 | 15 | } 16 | /* var arr =[] 17 | makeSingleArray(items,arr) 18 | //console.log(arr) 19 | 20 | */ 21 | 22 | module.exports={makeSingleArray} -------------------------------------------------------------------------------- /plugins/nodeSrc/reprocess.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | function reprocess(data) { 4 | console.log(data) 5 | try { 6 | let current = JSON.parse(fs.readFileSync('content.json').toString()) 7 | //before delta 8 | console.log(current.length) 9 | data.forEach(delta => { 10 | current = current.filter(cur => cur?.resource !== delta?.resource && cur?.controlId !== delta?.controlId) 11 | }) 12 | //after removal 13 | data.forEach(delta => current.push(delta)) 14 | 15 | 16 | //after removal 17 | console.log(current.length) 18 | return current 19 | } catch (error) { 20 | console.log('no previous file, or unable to parse content.json, contents of JSON overwritten') 21 | return data 22 | } 23 | 24 | } 25 | 26 | 27 | module.exports={reprocess} -------------------------------------------------------------------------------- /plugins/nodeSrc/returnObjectInit.js: -------------------------------------------------------------------------------- 1 | function returnObjectInit (item,filename) { 2 | 3 | this.name = item.name 4 | this.id = item.id 5 | this.fileName = filename 6 | this.isHealthy = false 7 | this.metadata = undefined 8 | 9 | return this 10 | 11 | } 12 | 13 | module.exports={returnObjectInit} -------------------------------------------------------------------------------- /plugins/nodeSrc/subProviderCheck.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | function checkSubProvider (provider) { 3 | 4 | try { 5 | let provP = provider.split('providers')[1].split('/')[1] + '/' +provider.split('providers')[1].split('/')[2] 6 | let proPath = path.resolve(`./providers/${provP}/.apiVersion.json`) 7 | let {apiversion} = require(proPath) 8 | return apiversion 9 | } catch (error) { 10 | let provNative = provider.split('providers')[1].split('/')[1] 11 | let proPath = path.resolve(`./providers/${provNative}/.apiVersion.json`) 12 | let {apiversion} = require(proPath) 13 | return apiversion 14 | } 15 | 16 | 17 | 18 | 19 | } 20 | 21 | function checkSubProviderResource (data) { 22 | 23 | try { 24 | let provP = data.id.split('providers')[1].split('/')[1] + '/' +data.id.split('providers')[1].split('/')[2] 25 | // Look for additional API file if the subprovider exists 26 | require('fs').readFileSync(path.resolve(`./providers/${provP}/.apiVersion.json`)) 27 | let provider = `${data.type.split('/')[0]}/${data.type.split('/')[1]}` 28 | 29 | return provider 30 | } catch (error) { 31 | let provider = data.type.split('/')[0] 32 | return provider 33 | } 34 | 35 | 36 | 37 | 38 | } 39 | 40 | module.exports={checkSubProvider,checkSubProviderResource} -------------------------------------------------------------------------------- /plugins/nodeSrc/testConnection.js: -------------------------------------------------------------------------------- 1 | const net = require('net'); 2 | 3 | 4 | 5 | 6 | 7 | 8 | function testConnection (host,port) { 9 | 10 | return new Promise((resolve,reject) => { 11 | 12 | const client = net.createConnection({ port, host,timeout:300, allowHalfOpen:true }, () => { 13 | // 'connect' listener. 14 | client.destroy() 15 | return resolve('connected') 16 | 17 | 18 | //return resolve('connection ok') 19 | }) 20 | client.on('end', () => { 21 | console.log('disconnected from server'); 22 | }) 23 | 24 | client.on('error', (err) => { 25 | return resolve(err) 26 | }) 27 | 28 | 29 | }) 30 | } 31 | 32 | 33 | module.exports={testConnection} -------------------------------------------------------------------------------- /plugins/nodeSrc/webAppConfig.js: -------------------------------------------------------------------------------- 1 | /* //web app config is fetched at multiple stages, so it makes sense to cache the result. 2 | Composite would be the best place to handle it, but also given the use case somewhat cumber some */ 3 | 4 | const { AzNodeRest } = require("./east") 5 | 6 | var waConfig 7 | 8 | async function getAzWebAppConfig (item) { 9 | 10 | if (waConfig == undefined) { 11 | waConfig=[] 12 | } 13 | 14 | let conf = waConfig.find(s => s.id == item.id ) 15 | 16 | if (!conf) { 17 | console.log('no cache entry for config of', item?.id) 18 | conf = await AzNodeRest(`${item.id}/config/web?`,'2018-11-01') 19 | waConfig.push(conf) 20 | } 21 | 22 | 23 | return conf 24 | 25 | } 26 | 27 | 28 | module.exports={getAzWebAppConfig} 29 | 30 | 31 | -------------------------------------------------------------------------------- /plugins/other/wordlist.json: -------------------------------------------------------------------------------- 1 | { 2 | "values":"bearer(?!\\s+\\*),sig,signature,secret,password,\\?code,\\?auth,authentication,eyj,SELECT,dbo,AccountKey=,token,pat:,\\?pat,\\&pat" 3 | } -------------------------------------------------------------------------------- /plugins/session/dontremove.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /providers/ignore.json: -------------------------------------------------------------------------------- 1 | ["microsoft.azureactivedirectory","microsoft.authorization","microsoft.general","microsoft.azuredevops"] -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/controls/APIM_JWTValidation.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "APIM_JWTValidation", 3 | "Category": "Access", 4 | "Description": "Prefer JWT validation for validation of API callers" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/controls/APIM_backEnd-credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "APIM_backEnd-credentials", 3 | "Category": "Access", 4 | "Description": "Review list of back-end credentials associated with Azure Api management." 5 | } -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/controls/APIM_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "APIM_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/controls/listAPI.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Review", 4 | "Description": "review list of API" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/functions/APIM_backEnd-credentials.js: -------------------------------------------------------------------------------- 1 | 2 | const { batchThrottledSimple } = require("../../../plugins/nodeSrc/batch") 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { makeSingleArray } = require("../../../plugins/nodeSrc/recursor") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | //returnObjectInit 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | var {apiversion} = getProviderApiVersion(item.id) 13 | 14 | returnObject.isHealthy="review" 15 | 16 | let backends = await AzNodeRest(`${item.id}/backends`,apiversion) 17 | returnObject.metadata={backends:JSON.stringify(backends)} 18 | 19 | return returnObject 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/functions/APIM_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('GatewayLogs","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.apimanagement/functions/disabled_APIM_JWTValidation.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | 14 | var {apiversion} = getProviderApiVersion(item.id) 15 | 16 | item = await AzNodeRest(`${item.id}/firewallRules/`,apiversion) 17 | 18 | var is = item?.value.filter((rules) => rules.name == "AllowAllWindowsAzureIps") 19 | 20 | if ( is.length > 0){ 21 | returnObject.isHealthy=false 22 | } 23 | 24 | returnObject.metadata = {item} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2020-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscription_amdcAlerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sub_alerts", 3 | "Category": "Protection", 4 | "Description": "[AZSK Migrated] Pending Microsoft Defender for Cloud(MDC) alerts must be resolved \r\n Based on the policies that are enabled in the subscription,Microsoft Defender for Cloudraises alerts (which are typically indicative of resources that MDC suspects might be under attack or needing immediate attention). It is important that these alerts/actions are resolved promptly in order to eliminate the exposure to attacks. " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscription_scanAuditLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "scanAuditLogs", 3 | "Category": "Logs", 4 | "Description": "\r\n\r\n**Review Azure Resource Manager operations which rely only on password authentication**\r\n\r\nThis item checks the appIdAcr value for Apps, and ``[\"http://schemas.microsoft.com/claims/authnmethodsreferences\"]`` claim for users. \r\n\r\n\r\n\r\n📑 You might see items in this check fail that are using trusted location, but not MFA. For privileged users even in trusted location it's recommended to use MFA \r\n\r\n**Example of failed item**\r\n\r\n![image](https://user-images.githubusercontent.com/58001986/154227400-c373d77b-52c5-4f4c-ab36-a24619c67255.png)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_ActivityLog.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Subscriptions_ActivityLog", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_DefenderCoverage.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Subscriptions_DefenderCoverage", 3 | "Category": "Protection", 4 | "Description": "Enabling Azure Defender brings PaaS and IaaS protection to applicable resourceTypes" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_IndirectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review Azure AD and Azure RBAC baseline for delegations made via lighthouse. Review following blog for more information https://securecloud.blog/2020/11/13/securing-azure-lighthouse-with-azure-policy-and-azure-privileged-identity-management-for-msps-and-customers/" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_PreventSubscriptionTransfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Subscriptions_PreventSubscriptionTransfer", 3 | "Category": "Access", 4 | "Description": "Don't allow transfer of subscriptions outside the tenant by default. Malicious actor could transfer the subscription to another tenant, while the billing relationship will remain within the compromized tenant" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_SecurityContact.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Subscriptions_MDCStatus", 3 | "Category": "Access", 4 | "Description": "Ensure security contact information is populated on the subscription" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_classicAdministrators.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sub_classicAdministrators", 3 | "Category": "Access", 4 | "Description": "Review list of administrators outside of Azure RBAC assignments, review following article for more information [Classic Administrators](https://docs.microsoft.com/en-us/security/benchmark/azure/baselines/cloud-services-security-baseline#31-maintain-an-inventory-of-administrative-accounts)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_locks.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Data", 4 | "Description": "Review if resources have locks to protect them" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_roleAssignments.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review Azure AD and Azure RBAC baseline" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_roleAssignmentsRG.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review Azure AD and Azure RBAC baseline" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/Subscriptions_roleAssignmentsRGAdvanced.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review Azure AD and Azure RBAC baseline" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/scanAuditLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "scanAuditLogs", 3 | "Category": "Logs", 4 | "Description": "\r\n\r\n**Review Azure Resource Manager operations which rely only on password authentication**\r\n\r\nThis item checks the appIdAcr value for Apps, and ``[\"http://schemas.microsoft.com/claims/authnmethodsreferences\"]`` claim for users. \r\n\r\n\r\n\r\n📑 You might see items in this check fail that are using trusted location, but not MFA. For privileged users even in trusted location it's recommended to use MFA \r\n\r\n**Example of failed item**\r\n\r\n![image](https://user-images.githubusercontent.com/58001986/154227400-c373d77b-52c5-4f4c-ab36-a24619c67255.png)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/controls/sub_classicAdministrators.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sub_classicAdministrators", 3 | "Category": "Access", 4 | "Description": "Review list of administrators outside of Azure RBAC assignments, review following article for more information [Classic Administrators](https://docs.microsoft.com/en-us/security/benchmark/azure/baselines/cloud-services-security-baseline#31-maintain-an-inventory-of-administrative-accounts)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/Subscriptions_DefenderCoverage.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | var subName = JSON.parse(process.env.subs).find(m => m.id == item.name)?.subName 11 | 12 | 13 | if (item?.id.match('databases')) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | try {var {apiversion} = getProviderApiVersion(item.id) 20 | var s = item.id.split('/')[1] + "/" +item.id.split('/')[2] 21 | var {value} = await AzNodeRest(`/${s}/providers/Microsoft.Security/pricings`,'2018-06-01') 22 | const settings= value.map(item => { 23 | var {name} = item 24 | return { 25 | name, 26 | tier:item.properties?.pricingTier 27 | } 28 | }) || "" 29 | 30 | 31 | returnObject.name = subName 32 | 33 | //returnObject.metadata = {settings:JSON.stringify(settings),subName } 34 | returnObject.metadata = {settings,subName } 35 | //console.log(stashOrig) 36 | 37 | return returnObject} catch(error) { 38 | 39 | returnObject.isHealthy="Review" 40 | returnObject.metadata = {message:"Unable to process this type of sub", error} 41 | return returnObject 42 | 43 | } 44 | 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/Subscriptions_IndirectAccess.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | module.exports = async function (item) { 7 | 8 | item.id = `/subscriptions/${item.name}/providers/microsoft.authorization` 9 | 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy=true 13 | 14 | try { 15 | 16 | var {value} = await AzNodeRest(`/subscriptions/${item.name}/providers/Microsoft.ManagedServices/registrationAssignments?$expandRegistrationDefinition=true`,"2020-02-01-preview") 17 | 18 | if (value.length > 0) { 19 | returnObject.isHealthy="review" 20 | } 21 | returnObject.metadata={indirectAccess:JSON.stringify(value)} 22 | return returnObject 23 | 24 | 25 | 26 | } catch(error) { 27 | 28 | 29 | returnObject.isHealthy="not applicable" 30 | returnObject.metadata={error: JSON.stringify(error)} 31 | return returnObject 32 | 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/Subscriptions_PreventSubscriptionTransfer.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | module.exports = async function (item) { 7 | 8 | item.id = `/subscriptions/${item.name}/providers/microsoft.authorization` 9 | 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy="false" 13 | 14 | try { 15 | 16 | let {properties} = await AzNodeRest(`/providers/Microsoft.Subscription/policies/default`,"2021-10-01") 17 | 18 | if (properties?.blockSubscriptionsLeavingTenant == true) { 19 | returnObject.isHealthy="true" 20 | } 21 | returnObject.metadata={blockSubscriptionsLeavingTenant:JSON.stringify(properties)} 22 | return returnObject 23 | 24 | 25 | 26 | } catch(error) { 27 | 28 | // Even with error return failure 29 | 30 | returnObject.metadata={error: JSON.stringify(error)} 31 | return returnObject 32 | 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/Subscriptions_classicAdministrators.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy=true 13 | try { 14 | 15 | 16 | item.id = `/subscriptions/${item.name}/providers/microsoft.authorization` 17 | 18 | let classicAdmins = await AzNodeRest(`${item.id}/classicadministrators`,'2015-06-01') 19 | 20 | if (classicAdmins?.value.length > 0) { 21 | returnObject.isHealthy="review" 22 | } 23 | 24 | returnObject.metadata = {classicAdmins:classicAdmins?.value} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | 30 | } catch (error) { 31 | returnObject.isHealthy="review" 32 | returnObject.metadata={error: JSON.stringify(error)} 33 | return returnObject 34 | } 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/Subscriptions_locks.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | module.exports = async function (item) { 7 | 8 | item.id = `/subscriptions/${item.name}/providers/microsoft.authorization` 9 | 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy="manual" 13 | 14 | try { 15 | 16 | var {value} = await AzNodeRest(`/subscriptions/${item.name}/providers/Microsoft.Authorization/locks`,"2016-09-01") 17 | 18 | if (value.length > 0) { 19 | returnObject.isHealthy="review" 20 | } 21 | returnObject.metadata={locks:JSON.stringify(value)} 22 | return returnObject 23 | 24 | 25 | 26 | } catch(error) { 27 | 28 | 29 | returnObject.isHealthy="not applicable" 30 | returnObject.metadata={error: JSON.stringify(error)} 31 | return returnObject 32 | 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /providers/microsoft.authorization/functions/disabled_sub_classicAdministrators.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy=true 13 | try { 14 | 15 | 16 | item.id = `/subscriptions/${item.name}/providers/microsoft.authorization` 17 | 18 | let classicAdmins = await AzNodeRest(`${item.id}/classicadministrators`,'2015-06-01') 19 | 20 | if (classicAdmins?.value.length > 0) { 21 | returnObject.isHealthy="review" 22 | } 23 | 24 | returnObject.metadata = {classicAdmins:classicAdmins?.value} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | 30 | } catch (error) { 31 | returnObject.isHealthy="not applicable" 32 | returnObject.metadata={error: JSON.stringify(error)} 33 | return returnObject 34 | } 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/aad_caEval.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aad_caEval", 3 | "Category": "Access", 4 | "Description": "Ensure the following policies are found MFA, Block Legacy Auth and session for admins" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/aad_ca_azureDevops.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aad_ca_azureDevops", 3 | "Category": "Access", 4 | "Description": "Checks if the currently signed-in user requires MFA to access" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/aad_counts.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aad_counts", 3 | "Category": "Access", 4 | "Description": "General report enhancements to display object counts etc" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/aad_diagnostics.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "This control is part of the combined items, review [AAD Combined](#east_general_aad_combined)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/adminsCa.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "This control is part of the combined items, review [AAD Combined](#east_general_aad_combined)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/basicAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "This control is part of the combined items, review [AAD Combined](#east_general_aad_combined)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/caPolicies.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "This control is part of the combined items, review [AAD Combined](#east_general_aad_combined)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/controls/consentSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "This control is part of the combined items, review [AAD Combined](#east_general_aad_combined)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/functions/aad_ca_azureDevops.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { decode } = require("jsonwebtoken") 4 | const { getAzDevopsStatus } = require("../../../plugins/nodeSrc/aadHelpers") 5 | const { erroResponseSchema } = require("../../../plugins/nodeSrc/functionResponseSchema") 6 | const { getAADIamToken } = require("../../../plugins/nodeSrc/getToken") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | var tkn =decode(await getAADIamToken()) 12 | 13 | 14 | 15 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 16 | 17 | let azd 18 | try { 19 | azd= await getAzDevopsStatus(tkn.oid) 20 | } catch(error) { 21 | returnObject.metadata={error} 22 | returnObject.isHealthy="not applicable" 23 | return returnObject 24 | } 25 | //console.log(stashOrig) 26 | returnObject.metadata=azd 27 | returnObject.isHealthy="review" 28 | return returnObject 29 | 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/functions/aad_counts.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { batchThrottledSimple } = require("../../../plugins/nodeSrc/batch") 5 | const { getGraphToken } = require("../../../plugins/nodeSrc/getToken") 6 | const { genericGraph } = require("../../../plugins/nodeSrc/graph") 7 | const { getAADCAPol } = require("../../../plugins/nodeSrc/aadHelpers") 8 | 9 | 10 | 11 | //AzNodeRest 12 | module.exports = async function (item) { 13 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 14 | //console.log(stashOrig) 15 | returnObject.metadata={} 16 | returnObject.isHealthy="manual" 17 | 18 | let counts = await mains() 19 | 20 | returnObject.metadata={counts} 21 | 22 | return returnObject 23 | 24 | } 25 | 26 | async function mains () { 27 | 28 | let graphToken = await getGraphToken() 29 | 30 | let ar = [ {'item':"devices"},{'item':"groups"},{'item':"applications"},{'item':"users"}] 31 | 32 | for await (let cat of ar) { 33 | 34 | let opt = { 35 | responseType: 'json', 36 | "method": "get", 37 | url: `https://graph.microsoft.com/v1.0/${cat.item}/$count`, 38 | headers: { 39 | ConsistencyLevel: "Eventual", 40 | 'content-type': "application/json", 41 | authorization: "Bearer " + graphToken 42 | } 43 | } 44 | 45 | 46 | cat.value = await genericGraph(opt).catch(error => console.log(error)) || "no value" 47 | 48 | } 49 | 50 | return ar 51 | 52 | } 53 | -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/functions/basicAuth.js: -------------------------------------------------------------------------------- 1 | const { default: axios } = require("axios") 2 | const { decode } = require("jsonwebtoken") 3 | const { getBasicAuthStatus, getMFAStatus } = require("../../../plugins/nodeSrc/aadHelpers") 4 | const { getAADIamToken } = require("../../../plugins/nodeSrc/getToken") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | const { runner } = require("../../../plugins/pluginRunner") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | var token = await getAADIamToken() 12 | 13 | 14 | var {oid} = decode(token) 15 | var data 16 | if ( process.env.checkMFA == 'true') { 17 | data = await getBasicAuthStatus(oid) 18 | } 19 | 20 | 21 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 22 | returnObject.name = item.name 23 | returnObject.id = item.name 24 | 25 | if (data?.appliedPol.length == 0) { 26 | returnObject.isHealthy=false 27 | } 28 | else { 29 | returnObject.isHealthy=true 30 | } 31 | 32 | returnObject.metadata = {result:data || "no result available process.env.checkMFA:false"} 33 | 34 | return returnObject 35 | 36 | } 37 | -------------------------------------------------------------------------------- /providers/microsoft.azureactivedirectory/functions/caPolicies.js: -------------------------------------------------------------------------------- 1 | const { default: axios } = require("axios") 2 | const { getCaPolicies } = require("../../../plugins/nodeSrc/aadHelpers") 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { runner } = require("../../../plugins/pluginRunner") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | var data = await getCaPolicies() 11 | 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | returnObject.name = item.name 14 | returnObject.id = item.name 15 | 16 | if (item?.properties) { 17 | returnObject.isHealthy=false 18 | } 19 | else { 20 | returnObject.isHealthy=true 21 | } 22 | 23 | returnObject.metadata = data 24 | 25 | return returnObject 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /providers/microsoft.azuredevops/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.azuredevops/controls/azdevops_listPipelines.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "azdevops_listOrganizations", 3 | "Category": "Access", 4 | "Description": "Review list of Azure Devops Pipeline logs" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.azuredevops/controls/azdevops_listServiceEndpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "azdevops_listOrganizations", 3 | "Category": "Access", 4 | "Description": "Review list of Azure Devops Endpoints" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.cdn/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-06-01"} -------------------------------------------------------------------------------- /providers/microsoft.cdn/.skip.json: -------------------------------------------------------------------------------- 1 | ["afdendpoints"] -------------------------------------------------------------------------------- /providers/microsoft.cdn/controls/cdn_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "cdn_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.cdn/controls/cdn_securityHeaders.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "cdn_securityHeaders", 3 | "Category": "access", 4 | "Description": "Ensure securityHeaders are set in CDN \r\n read more [here](https://docs.microsoft.com/en-us/azure/frontdoor/front-door-security-headers#add-a-content-security-policy-header-in-azure-portal)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.cdn/controls/cdn_waf.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "cdn_waf", 3 | "Category": "Network", 4 | "Description": "Checks for existence of Web Application Firewall" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.cdn/functions/cdn_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('category":"FrontDoorAccessLog","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.cdn/functions/cdn_securityHeaders.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | let ruleList = [] 13 | 14 | returnObject.isHealthy="review" 15 | 16 | try { 17 | 18 | const {value:rules} = await AzNodeRest(`${item.id}/ruleSets?`,'2021-06-01') 19 | 20 | for await (let rule of rules) { 21 | 22 | ruleList.push(await AzNodeRest(`${item.id}/ruleSets/${rule.name}/rules`,'2021-06-01')) 23 | } 24 | 25 | } catch (error) { 26 | returnObject.isHealthy="manual" 27 | } 28 | 29 | 30 | let headerMatch = JSON.stringify(ruleList).match('"headerName":') 31 | 32 | if (headerMatch) { 33 | returnObject.isHealthy=true 34 | } 35 | 36 | 37 | returnObject.metadata = {headersArePresent:JSON.stringify(headerMatch?.input) || "it appears no security headers are set, since there are no header rules present"} 38 | //console.log(stashOrig) 39 | 40 | return returnObject 41 | 42 | } 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /providers/microsoft.cdn/functions/cdn_waf.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | let securityPolicies = await AzNodeRest(`${item.id}/securityPolicies?`,'2021-06-01') 13 | 14 | 15 | returnObject.metadata = {securityPolicies} 16 | //console.log(stashOrig) 17 | 18 | return returnObject 19 | 20 | } 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.compute/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-11-01"} -------------------------------------------------------------------------------- /providers/microsoft.compute/.skip.json: -------------------------------------------------------------------------------- 1 | ["microsoft.compute/disks","microsoft.compute/virtualmachinescalesets/","extensions/databricksbootstrap","microsoft.compute/snapshots","microsoft.compute/sshpublickeys"] -------------------------------------------------------------------------------- /providers/microsoft.compute/controls/Compute_PolicyGuestConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Compute_PolicyGuestConfig", 3 | "Category": "Hardening", 4 | "Description": "Guest Configuration definitions in Azure Policy allow you to validate settings inside virtual machines. This includes the configuration of the Operating System, applications, or even environmental data. You can use this API to create or update Guest Configuration, and get information about the compliance details of a virtual machine including which specific settings are not compliant with the assigned configuration." 5 | } -------------------------------------------------------------------------------- /providers/microsoft.compute/controls/VM_Endpoint.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "VM_endpointProtection", 3 | "Category": "Protection", 4 | "Description": "ASB:Install endpoint protection solution on virtual machines" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.compute/controls/VM_ManagedIdentity.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "VM_ManagedIdentity", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.compute/controls/VM_PublicIP.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "VM_PublicIP", 3 | "Category": "Network", 4 | "Description": "ASB:All network ports should be restricted on network security groups associated to your virtual machine" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.compute/controls/VM_SSH_linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "VM_LinuxSSH", 3 | "Category": "Protection", 4 | "Description": "ASB:Authentication to Linux machines should require SSH key" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.compute/functions/Compute_PolicyGuestConfig.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (!item?.type.match('microsoft.compute/virtualmachines') ||item?.id.match('/extensions') || item.id.match('virtualmachinescalesets') ) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | returnObject.isHealthy="review" 20 | 21 | let AzurePolicy 22 | 23 | if (item?.resources) { 24 | AzurePolicy =item?.resources.find(extension => extension.name == "AzurePolicyforLinux"|| "AzurePolicyForWindows" ) || "No Policy Agent" 25 | 26 | if (AzurePolicy?.properties?.provisioningState) { 27 | returnObject.isHealthy = true 28 | delete AzurePolicy.properties 29 | } 30 | } 31 | 32 | 33 | 34 | returnObject.metadata = {AzurePolicy: AzurePolicy || "not applicable" } 35 | //console.log(stashOrig) 36 | 37 | return returnObject 38 | 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /providers/microsoft.compute/functions/VM_ManagedIdentity.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 2 | const { getGraphToken } = require("../../../plugins/nodeSrc/getToken") 3 | const { graph } = require("../../../plugins/nodeSrc/graph") 4 | const { checkRoles } = require("../../../plugins/nodeSrc/listRoles") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 7 | const { iterateMI } = require("../../../plugins/nodeSrc/miGeneral") 8 | module.exports = async function (item) { 9 | 10 | 11 | 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | 14 | 15 | if (!item?.id.match('/microsoft.compute/virtualmachines') ||item?.id.match('/extensions') ) { 16 | returnObject.metadata = {} 17 | returnObject.isHealthy="notApplicable" 18 | return returnObject 19 | } 20 | 21 | let identityList 22 | try {identityList = await iterateMI(item)} catch(err) { 23 | console.log(err) 24 | 25 | } 26 | 27 | 28 | 29 | returnObject.name = item.name 30 | returnObject.id = item.id 31 | returnObject.metadata = {identityList} 32 | 33 | return returnObject 34 | } 35 | -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-12-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/controls/acr_DiagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "acr_DiagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/controls/acr_adminUser.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "acr_fireWall", 3 | "Category": "Access", 4 | "Description": "Only allow non AAD based authentication on the registry if network restrictions are enabled on the registry" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/controls/acr_anonymousPull.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "acr_fireWall", 3 | "Category": "Data", 4 | "Description": "Do not allow anonymous pull on the registry unless registry is meant be public registry" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/controls/acr_fireWall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "acr_fireWall", 3 | "Category": "Network", 4 | "Description": "It is recommended to limit the callers of the service by IP addresses, VNET or to private endpoints when callers of the service can be subjected to network requirements" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/functions/acr_DiagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('ContainerRegistryRepositoryEvents","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | try { 22 | var loginLogs =JSON.stringify(diagnostics).match('ContainerRegistryLoginEvents","categoryGroup":null,"enabled":true')[0] 23 | } catch (error) { 24 | console.log() 25 | } 26 | 27 | 28 | 29 | 30 | 31 | returnObject.metadata = {loginLogs: loginLogs || "no login logs",logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 32 | //console.log(stashOrig) 33 | 34 | return returnObject 35 | 36 | } 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/functions/acr_adminUser.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | let metadata = {} 13 | 14 | if (item.properties?.adminUserEnabled == false ) { 15 | returnObject.isHealthy = true 16 | } 17 | 18 | // Change to healthy, if network rules are used 19 | if ((item.properties?.networkRuleSet?.ipRules?.length > 0 || item.properties?.networkRuleSet?.virtualNetworkRules?.length > 0 )) { 20 | returnObject.isHealthy = true 21 | } 22 | 23 | metadata.adminUserEnabled = item.properties?.adminUserEnabled 24 | 25 | 26 | returnObject.metadata = {adminUserEnabled:item.properties?.adminUserEnabled } 27 | //console.log(stashOrig) 28 | 29 | return returnObject 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/functions/acr_anonymousPull.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | returnObject.isHealthy = true 13 | if (item.properties?.anonymousPullEnabled == true ) { 14 | returnObject.isHealthy = false 15 | } 16 | 17 | returnObject.metadata = {anonymousPullEnabled:item.properties?.anonymousPullEnabled } 18 | //console.log(stashOrig) 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.containerregistry/functions/acr_fireWall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item.properties?.networkRuleSet?.ipRules?.length > 0 || item.properties?.networkRuleSet?.virtualNetworkRules.length > 0 ) { 14 | returnObject.isHealthy = true 15 | } 16 | 17 | returnObject.metadata = item.properties?.networkRuleSet|| {} 18 | //console.log(stashOrig) 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-11-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/ContainerService_AKSLocalAdmin.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\nEnsure AAD Cant be bypassed via admin flag\n", 3 | "Category": "Access", 4 | "Description": "\nWhen deploying an AKS Cluster, local accounts are enabled by default. Even when enabling RBAC or Azure Active Directory integration, --admin access still exists, essentially as a non-auditable backdoor option -- Verbatum [MS Docs](https://docs.microsoft.com/en-us/azure/aks/managed-aad#disable-local-accounts-preview) \n\n**Check the control**\n```BASH\naz aks show --resource-group RG-aks-refInstall --name akssvc5 -o json --query \"disableLocalAccounts\"\n``` \n\n\n\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/ContainerService_DiagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "ContainerService_DiagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/ContainerService_EphemeralDisk.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "ContainerService_EphemeralDisk", 3 | "Category": "Review", 4 | "Description": "Using Ephemeral disk ensures, that no Cluster state persist outside of the AKS VM" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_PolicyState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aks_PolicyState", 3 | "Category": "Data", 4 | "Description": "Review policy failures on component levels" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_apiServer.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aks_apiServer", 3 | "Category": "Access", 4 | "Description": "Ensure API server does not allow" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_audit_useOfExec.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\nEnsure use of Exec is Audited for users\n", 3 | "Category": "Logs", 4 | "Description": "\nWhile there is lot of use cases for exec, malicious users can use exec to traverse lateraly withing the cluster. Audit the use of exec in production clusters, where the use of exec is deemed to be low\n\n```powershell\nAzureDiagnostics\n| where TimeGenerated > now()-30m\n| where Category == \"kube-audit\"\n| extend l= parse_json(log_s)\n| where l.objectRef.subresource == \"exec\"\n| distinct tostring(l.user), tostring(l.responseObject.message)\n```\n\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_getPublicWorkLoads.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aks_getPublicWorkLoads", 3 | "Category": "Review", 4 | "Description": "Review Public Workloads" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_kubenetARPSpoof.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aks_kubenetARPSpoof", 3 | "Category": "Access", 4 | "Description": "Kubenet network plugin is susceptible to ARP spoofing. This makes it possible for pods to impersonate as a pod with access to an identity. Using CAP_NET_RAW capability the attacker pod could then request token as a pod it's impersonating.Network plugins like Azure CNI, Calico, Cilium prevents ARP Spoofing. https://github.com/Azure/aad-pod-identity/blob/master/website/content/en/docs/Configure/aad_pod_identity_on_kubenet.md#why-this-change" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/controls/aks_networkPolicy.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "aks_networkPolicy", 3 | "Category": "Network", 4 | "Description": "Using network policies allows the use inter-cluster network security rules. Without network policy cluster can't have any inter-cluster network security rules active \r\n https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/innovate/kubernetes/cluster-application-security#deploy-to-production-and-apply-kubernetes-security-best-practices" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/ContainerService_AKSLocalAdmin.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | const { runner } = require("../../../plugins/pluginRunner") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | if (!item?.id.match('managedclusters')) { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } 17 | 18 | var token = await runner('az account get-access-token --resource=https://management.core.windows.net/ --query accessToken --output json') 19 | var {apiversion} = getProviderApiVersion(item.id) 20 | var options = { 21 | url:`https://management.azure.com${item.id}?api-version=${apiversion}`, 22 | headers:{ 23 | Authorization: `Bearer ${token}` 24 | } 25 | } 26 | item = await AzNodeRest(undefined,undefined,undefined,options) 27 | 28 | 29 | //item = await AzNodeRest(item.id,apiversion) 30 | 31 | 32 | returnObject.isHealthy=true 33 | if (item?.properties?.disableLocalAccounts == false ){ 34 | returnObject.isHealthy=false 35 | } 36 | 37 | 38 | returnObject.metadata = {disableLocalAccounts:item?.properties?.disableLocalAccounts} 39 | //console.log(stashOrig) 40 | 41 | return returnObject 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/ContainerService_DiagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | if (!item?.id.match('managedClusters')) { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } 17 | 18 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 19 | 20 | try { 21 | var apiServer =JSON.stringify(diagnostics).match('apiserver\\",\\"categoryGroup\\":null,\\"enabled\\":true')[0] 22 | var admin =JSON.stringify(diagnostics).match('kube-audit-admin\\",\\"categoryGroup\\":null,\\"enabled\\":true')[0] 23 | } catch (error) { 24 | console.log() 25 | } 26 | 27 | 28 | if (admin && apiServer){ 29 | returnObject.isHealthy=true 30 | } 31 | 32 | 33 | returnObject.metadata = {apiServer:apiServer || "not enabled", admin:admin || "not enabled"} 34 | //console.log(stashOrig) 35 | 36 | return returnObject 37 | 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/ContainerService_EphemeralDisk.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (!item?.id.match('managedclusters')) { 12 | returnObject.metadata = item?.properties 13 | returnObject.isHealthy="notApplicable" 14 | return returnObject 15 | } 16 | 17 | if ( item?.properties?.agentPoolProfiles[0]?.osDiskType == true){ 18 | returnObject.isHealthy=true 19 | } 20 | 21 | returnObject.metadata = {osDiskType: item?.properties?.agentPoolProfiles[0]?.osDiskType} 22 | //console.log(stashOrig) 23 | 24 | return returnObject 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_apiServer.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | if (item?.properties?.apiServerAccessProfile) { 10 | returnObject.isHealthy=true 11 | } 12 | 13 | returnObject.metadata={apiServerAccessProfile: item?.properties?.apiServerAccessProfile|| "No API server restrictions"} 14 | return returnObject 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_audit_useOfExec.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | returnObject.metadata={} 10 | returnObject.isHealthy="manual" 11 | return returnObject 12 | 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_getPublicWorkLoads.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { default: axios } = require("axios") 4 | const { randomUUID } = require("crypto") 5 | const { decode } = require("jsonwebtoken") 6 | const { axiosClient } = require("../../../plugins/nodeSrc/axioshelpers") 7 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 8 | const { getAKStoken } = require("../../../plugins/nodeSrc/getToken") 9 | 10 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 11 | const { runner } = require("../../../plugins/pluginRunner") 12 | 13 | 14 | //AzNodeRest 15 | module.exports = async function (item) { 16 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 17 | 18 | 19 | //var tkn = await runner('az account get-access-token --resource=6dae42f8-4368-4678-94ff-3960e28e3630 --query accessToken --output json') 20 | var tkn = await getAKStoken() 21 | let customOpt = { 22 | url:`https://${item.properties?.azurePortalFQDN}/api/v1/services?limit=200`, 23 | method:"get", 24 | timeout:2000, 25 | headers:{ 26 | authorization: `Bearer ${tkn}`, 27 | 'kubectl-session': randomUUID() 28 | } 29 | } 30 | 31 | try{ 32 | const {data} = await axios(customOpt) 33 | console.log(data) 34 | returnObject.metadata=data 35 | } catch (error) { 36 | //console.log(error ) 37 | returnObject.metadata={error:error?.message} 38 | } 39 | 40 | 41 | returnObject.isHealthy="manual" 42 | return returnObject 43 | 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_kubenetARPSpoof.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | returnObject.isHealthy=true 9 | if (item?.properties?.networkProfile?.networkPlugin.match('kubenet')) { 10 | returnObject.isHealthy=false 11 | } 12 | 13 | returnObject.metadata=item.properties.networkProfile 14 | return returnObject 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_networkPolicy.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | if (item?.properties?.networkProfile?.networkPlugin.toString().length > 3) { 11 | returnObject.isHealthy=true 12 | } 13 | returnObject.metadata=item?.properties?.networkProfile || {} 14 | return returnObject 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/aks_networking.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | returnObject.metadata={} 10 | returnObject.isHealthy="manual" 11 | return returnObject 12 | 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/disabled_aks_1getPublicWorkLoads.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { default: axios } = require("axios") 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | /* const { getAKStoken } = require("../../../plugins/nodeSrc/getToken") */ 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | //console.log(stashOrig) 13 | /* var token = await getAKStoken() 14 | let customOpt = { 15 | url:`https://${item.properties?.azurePortalFQDN}/apis/apps/v2/deployments?limit=200`, 16 | method:"get", 17 | headers:{ 18 | authorizaton: `Bearer ${token}` 19 | } 20 | } 21 | 22 | const deployments = await AzNodeRest(undefined,undefined ,undefined,customOpt) 23 | */ 24 | returnObject.metadata={} 25 | returnObject.isHealthy="manual" 26 | return returnObject 27 | 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /providers/microsoft.containerservice/functions/pod_security-policyMapping.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | //console.log(stashOrig) 11 | returnObject.metadata={} 12 | returnObject.isHealthy="manual" 13 | return returnObject 14 | 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /providers/microsoft.databricks/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.databricks/controls/databricks_auditClustersForNoIsolation.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "databricks_auditClustersForNoIsolation", 3 | "Category": "Data", 4 | "Description": "Audits Databricks clusters for potential privilege elevation, based on [advisory](https://www.databricks.com/blog/2022/10/10/admin-isolation-shared-clusters.html)
- This control requires typically permissions beyond reader" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.databricks/controls/databricks_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "databricks_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.databricks/controls/databricks_skuCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "databricks_skuCheck", 3 | "Category": "Data", 4 | "Description": "Since standard SKU is not supporting ACL we check the use of Premium SKU" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.databricks/functions/databricks_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('categoryGroup":"allLogs","enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.databricks/functions/databricks_skuCheck.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | var returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item?.sku?.name == "premium") { 14 | returnObject.isHealthy = true 15 | } 16 | 17 | 18 | returnObject.metadata = {sku:item?.sku?.name} 19 | //console.log(stashOrig) 20 | 21 | return returnObject 22 | 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /providers/microsoft.datafactory/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2018-06-01"} -------------------------------------------------------------------------------- /providers/microsoft.datafactory/controls/ADF_Linked_Services.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "ADF_Linked_Services", 3 | "Category": "Access", 4 | "Description": "\r\n\r\n[source](https://docs.microsoft.com/en-us/security/benchmark/azure/baselines/data-factory-security-baseline#im-7-eliminate-unintended-credential-exposure)\r\n\r\nIf you’re using Data Factory’s visual UI-based authoring tool, then all credentials and secrets stored in linked services are either directly encrypted by the service or can be referenced by runtime using key vault. So no credentials as such will show up in the JSON code. These credentials can never be retrieved by code or visual UI. \r\n-\tIn this report failed credentials are marked as \"safeCredential\": false” the recommendation is store all secrets into Key Vault.\r\n\r\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.datafactory/controls/ADF_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "ADF_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.datafactory/controls/ADF_pipeLineRuns.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "ADF_Linked_Services", 3 | "Category": "Data", 4 | "Description": "\r\n\r\n[source](https://docs.microsoft.com/en-us/security/benchmark/azure/baselines/data-factory-security-baseline#im-7-eliminate-unintended-credential-exposure)\r\n\r\nIf you’re using Data Factory’s visual UI-based authoring tool, then all credentials and secrets stored in linked services are either directly encrypted by the service or can be referenced by runtime using key vault. So no credentials as such will show up in the JSON code. These credentials can never be retrieved by code or visual UI. \r\n-\tIn this report failed credentials are marked as \"safeCredential\": false” the recommendation is store all secrets into Key Vault.\r\n\r\n this will also check for variables containing plaintext secrets" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.datafactory/controls/ADF_pipeline_clearTextVariables.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "adf_pipeline_svc_mapping", 3 | "Category": "Data", 4 | "Description": "Review if pipelines expose cleartext credentials in variables" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.datafactory/controls/ADF_pipeline_svc_mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "adf_pipeline_svc_mapping", 3 | "Category": "Data", 4 | "Description": "Review how pipelines map to linked credentials" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.datafactory/functions/ADF_Linked_Services.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item?.id.match('databases')) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | var {apiversion} = getProviderApiVersion(item.id) 20 | 21 | var {value:linkedSvc} = await AzNodeRest(`${item.id}/linkedservices?`,apiversion) 22 | returnObject.isHealthy=true 23 | var list= linkedSvc.map(svc => { 24 | svc.safeCredential = true 25 | delete svc.id 26 | delete svc.etag 27 | delete svc.type 28 | if (JSON.stringify(svc).match('encrypted')) { 29 | returnObject.isHealthy=false 30 | svc.safeCredential=false 31 | svc.properties.typeProperties.encryptedCredential = `${svc.properties.typeProperties.encryptedCredential.substring(0,10)}...REDACTED` 32 | } 33 | if (svc.properties.annotations.length == 0) { 34 | delete svc.properties.annotations 35 | } 36 | return {svc:JSON.stringify(svc)} 37 | }) 38 | 39 | returnObject.metadata = {list} 40 | //console.log(stashOrig) 41 | 42 | return returnObject 43 | 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /providers/microsoft.datafactory/functions/ADF_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('ActivityRuns","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.datafactory/functions/ADF_pipeline_clearTextVariables.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { azNodeRestRef, azNodeRestRefDyn } = require("../../../plugins/nodeSrc/nodeRestRef") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | 14 | 15 | var {apiversion} = getProviderApiVersion(item.id) 16 | 17 | var {value:pipelines} = await AzNodeRest(`${item.id}/pipelines?`,apiversion) 18 | 19 | let matchLikelySecrets = pipelines.map(c => { 20 | 21 | let r = require('../../../plugins/other/wordlist.json').values.split(',').map(word => { 22 | let srs = JSON.stringify(c).toLowerCase().match(word.toLowerCase()) 23 | // let srs2 = JSON.stringify(item.properties.definition).toLowerCase().match(new RegExp("\\?code",'g')) 24 | if (srs) { 25 | console.log() 26 | returnObject.isHealthy="review" 27 | } 28 | return srs 29 | }).filter(is => is !== null).map(s => `${c.name}:${s.input.substring(s.index-30,s.index+30)}`) 30 | 31 | return r 32 | 33 | 34 | }).filter(s => s.length > 0) 35 | 36 | 37 | 38 | 39 | returnObject.isHealthy="manual" 40 | returnObject.metadata = {matchLikelySecrets} 41 | //console.log(stashOrig) 42 | 43 | return returnObject 44 | 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2017-12-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/controls/mysql_TLSversionEnforcement.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "mysql_TLSversionEnforcement", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/controls/mysql_firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "mysql_firewall", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/controls/mysql_sslEnforceMent.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "mysql_sslEnforceMent", 3 | "Category": "Access", 4 | "Description": "Ensure secure connection is required for all connections" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/functions/mysql_TLSversionEnforcement.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | if (item?.properties?.minimalTlsVersion == "TLS1_2") { 11 | returnObject.isHealthy = true 12 | } 13 | 14 | returnObject.metadata={minimalTlsVersion:item?.properties?.minimalTlsVersion} 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/functions/mysql_firewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item?.id.match('databases')) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | var {apiversion} = getProviderApiVersion(item.id) 20 | 21 | item = await AzNodeRest(`${item.id}/firewallRules/`,apiversion) 22 | 23 | var is = item?.value.filter((rules) => rules.name == "AllowAllWindowsAzureIps") 24 | 25 | if ( is.length > 0 || item?.value.length == 0){ 26 | returnObject.isHealthy=false 27 | } 28 | 29 | returnObject.metadata = {item} 30 | //console.log(stashOrig) 31 | 32 | return returnObject 33 | 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /providers/microsoft.dbformysql/functions/mysql_sslEnforceMent.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | if (item?.properties?.sslEnforcement !== "Disabled") { 11 | returnObject.isHealthy = true 12 | } 13 | 14 | returnObject.metadata={sslEnforcement:item?.properties?.sslEnforcement} 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2017-12-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/.skip.json: -------------------------------------------------------------------------------- 1 | ["microsoft.dbforpostgresql/flexibleservers/"] -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/controls/psql_TLSVersionEnforcement.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "psql_TLSVersionEnforcement", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/controls/psql_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "psql_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/controls/psql_fireWall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Network", 4 | "Description": "\n“Allow Azure services and resources to access this server” setting for SQL allows a trivial bypass for Azure firewall. Essentially meaning, that if attacker gets the SQL connection string, the protection by network rules does very little to protect from the attack. \n- Unfortunately many Azure Services rely on this setting to access SQL. Consider using this setting only if managed identities are in the ACL for SQL\n \n![image](https://user-images.githubusercontent.com/58001986/156122091-4e9f7fbb-54eb-4f4c-9c67-cf5234cc8ce1.png)\n\n\n\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/controls/psql_sslEnforcement.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "psql_sslEnforcement", 3 | "Category": "Access", 4 | "Description": "Ensure secure connection is required for all connections" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/functions/psql_TLSVersionEnforcement.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | if (item?.properties?.minimalTlsVersion == "TLS1_2") { 11 | returnObject.isHealthy = true 12 | } 13 | 14 | returnObject.metadata={minimalTlsVersion:item?.properties?.minimalTlsVersion} 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/functions/psql_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('PostgreSQLLogs","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/functions/psql_fireWall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item?.id.match('databases')) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | returnObject.isHealthy=true 20 | var {apiversion} = getProviderApiVersion(item.id) 21 | 22 | item = await AzNodeRest(`${item.id}/firewallRules/`,apiversion) 23 | 24 | var is = item?.value.filter((rules) => rules.name == "AllowAllWindowsAzureIps") 25 | 26 | if ( is.length > 0 || item?.value.length == 0){ 27 | returnObject.isHealthy=false 28 | } 29 | 30 | 31 | returnObject.metadata = {item} 32 | //console.log(stashOrig) 33 | 34 | return returnObject 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /providers/microsoft.dbforpostgresql/functions/psql_sslEnforcement.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | if (item?.properties?.sslEnforcement !== "Disabled") { 11 | returnObject.isHealthy = true 12 | } 13 | 14 | returnObject.metadata={sslEnforcement:item?.properties?.sslEnforcement} 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /providers/microsoft.devices/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-07-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.devices/controls/EnforceX509.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "EnforceX509", 3 | "Category": "Access", 4 | "Description": "Ensure X509 scheme is instead of string based tokens" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.devices/controls/IOT_DisableLocalAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "IOT_DisableLocalAuth", 3 | "Category": "access", 4 | "Description": "AzPol: Disable local authentication methods so that your Azure IoT Hub exclusively require Azure Active Directory identities for authentication. Learn more at: https://aka.ms/iothubdisablelocalauth." 5 | } -------------------------------------------------------------------------------- /providers/microsoft.devices/controls/IOT_Firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "IOT_Firewall", 3 | "Category": "Network", 4 | "Description": "Ensure firewall is enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.devices/controls/IOT_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "IOT_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.devices/functions/EnforceX509.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | 10 | if (!item?.id.match('IotHubs')) { 11 | returnObject.metadata = item?.properties 12 | returnObject.isHealthy="notApplicable" 13 | return returnObject 14 | } 15 | 16 | returnObject.isHealthy=false 17 | if ( item?.properties?.disableDeviceSAS == true && item?.properties?.disableModuleSAS == true){ 18 | returnObject.isHealthy=true 19 | } 20 | 21 | 22 | 23 | returnObject.metadata = {SASAuthDisabled:item?.properties?.disableDeviceSAS || ["SAS Auth is enabled"]} 24 | //console.log(stashOrig) 25 | 26 | return returnObject 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /providers/microsoft.devices/functions/IOT_DisableLocalAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | 10 | if (!item?.id.match('IotHubs')) { 11 | returnObject.metadata = item?.properties 12 | returnObject.isHealthy="notApplicable" 13 | return returnObject 14 | } 15 | 16 | if ( item?.properties?.disableLocalAuth == true){ 17 | returnObject.isHealthy=true 18 | } else { 19 | returnObject.isHealthy=false 20 | } 21 | 22 | 23 | 24 | returnObject.metadata = {localAuth:item?.properties?.disableLocalAuth || ['local auth is enabled']} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /providers/microsoft.devices/functions/IOT_Firewall.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | var {apiversion} = getProviderApiVersion(item.id) 12 | var fw = item.properties.ipFilterRules 13 | returnObject.isHealthy=false 14 | if ( fw.length > 0){ 15 | returnObject.isHealthy=true 16 | } 17 | 18 | if (fw.length > 0) {fw=fw} else {fw=["No fw settings enabled"]} 19 | 20 | returnObject.metadata = {fw} 21 | //console.log(stashOrig) 22 | 23 | return returnObject 24 | 25 | } 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /providers/microsoft.devices/functions/IOT_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('Connections","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.documentdb/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.documentdb/controls/Microsoft.DocumentDb_Firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Microsoft.DocumentDb_Firewall", 3 | "Category": "Network", 4 | "Description": "Ensure firewall is enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.documentdb/functions/Microsoft.DocumentDb_Firewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | 14 | var accessControls = (item?.properties?.ipRules || item?.properties?.isVirtualNetworkFilterEnabled ) 15 | 16 | if (accessControls.length > 0) { 17 | returnObject.isHealthy=true 18 | } 19 | 20 | returnObject.metadata = {accessControls: accessControls || "no access controls"} 21 | //console.log(stashOrig) 22 | 23 | return returnObject 24 | 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /providers/microsoft.eventhub/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-11-01"} -------------------------------------------------------------------------------- /providers/microsoft.eventhub/controls/eh_avoidNamespacePolicies.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_avoidNamespacePolicies", 3 | "Category": "Access", 4 | "Description": "\n\nAZSK Migrated: Azure_EventHub_AuthZ_Dont_Use_Policies_At_Event_Hub_Namespace \n\n*A ‘namespace’ level access policy provides access to all Event Hub in a namespace. However, using an access policy at entity (Event Hub) level provides access only to the specific entity. Thus using the latter is inline with the principle of least privilege.*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.eventhub/controls/eh_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.eventhub/controls/eh_disableLocalAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_disableLocalAuth", 3 | "Category": "Access", 4 | "Description": "\n[source](https://docs.microsoft.com/en-us/azure/event-hubs/policy-reference)\n\n*Disabling local authentication methods improves security by ensuring that Azure Event Hub namespaces exclusively require Azure Active Directory identities for authentication. Learn more at: https://aka.ms/disablelocalauth-eh.*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.eventhub/controls/eh_firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_avoidNamespacePolicies", 3 | "Category": "Network", 4 | "Description": "Enable network restrictions If consumers of service can be identified by static network conditions" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.eventhub/controls/eh_useAzureRBACforDataAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_useAzureRBACforDataAccess", 3 | "Category": "Access", 4 | "Description": "\n[source](https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-shared-access-signature#what-are-shared-access-signatures)\n\n*Azure Event Hubs supports authorizing to Event Hubs resources using Azure Active Directory (Azure AD). Authorizing users or applications using OAuth 2.0 token returned by Azure AD provides superior security and ease of use over shared access signatures (SAS). With Azure AD, there is no need to store the tokens in your code and risk potential security vulnerabilities.*\n\n*Microsoft recommends using Azure AD with your Azure Event Hubs applications when possible. For more information, see Authorize access to Azure Event Hubs resource using Azure Active Directory.*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.eventhub/functions/eh_avoidNamespacePolicies.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { azNodeRestRef } = require("../../../plugins/nodeSrc/nodeRestRef") 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | //console.log(stashOrig) 10 | 11 | let {value} = await azNodeRestRef(`${item.id}/authorizationRules`,'2017-04-01') 12 | let nameSpaceLevel = value.filter(s => !s.name.match('RootManageSharedAccessKey')) 13 | 14 | if (!nameSpaceLevel.length > 0) { 15 | returnObject.isHealthy=true 16 | } 17 | 18 | returnObject.metadata=nameSpaceLevel 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.eventhub/functions/eh_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('OperationalLogs","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.eventhub/functions/eh_disableLocalAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | if (item?.properties?.disableLocalAuth == true) { 10 | returnObject.isHealthy = true 11 | } 12 | 13 | returnObject.metadata=item.properties 14 | return returnObject 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /providers/microsoft.eventhub/functions/eh_firewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | 10 | let {properties:networkSettings} = await AzNodeRest(`${item.id}/networkrulesets/default`,'2021-06-01-preview') 11 | returnObject.isHealthy=true 12 | 13 | if (networkSettings.ipRules.length == 0 && networkSettings.virtualNetworkRules.length == 0) { 14 | returnObject.isHealthy=false 15 | } 16 | 17 | returnObject.metadata=networkSettings 18 | 19 | return returnObject 20 | 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /providers/microsoft.general/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-04-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.general/functions/general_aad_combined.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | //console.log(stashOrig) 12 | returnObject.metadata={} 13 | return returnObject 14 | 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /providers/microsoft.general/functions/general_aadauthnz.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | returnObject.metadata={} 10 | returnObject.isHealthy="manual" 11 | return returnObject 12 | 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /providers/microsoft.general/functions/general_auditLogs.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | const returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | item.isHealthy = "manual" 13 | returnObject.metadata = {item} 14 | //console.log(stashOrig) 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /providers/microsoft.keyvault/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2019-09-01"} -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/KeyVault_AdvancedCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "KeyVault_AdvancedCheck", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/KeyVault_Firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "KeyVault_Firewall", 3 | "Category": "Network", 4 | "Description": "Ensure Azure KeyVault is enabled for firewall when Azure KeyVault consumers support network restrictions" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/KeyVault_ReviewListOfCallers.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "KeyVault_AdvancedCheck", 3 | "Category": "Access", 4 | "Description": "Review list of distinct consumers of the Key Vault. This function produces results when the Key Vault has export settings enabled for Log Analytics workspace" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/KeyVault_accessPolicies.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "KeyVault_AP", 3 | "Category": "Access", 4 | "Description": "Review Azure Key Vault Access Policies" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/Keyvault_ReviewAdvancedAccessPolicies.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Keyvault_ReviewAdvancedAccessPolicies", 3 | "Category": "Access", 4 | "Description": "\n//Migrated from AZSK\n\nAdvanced access policy allows Azure services (Azure Resource Manager, Virtual Machine, Disk Encryption etc.) to seamlessly access Key Vault. To avoid unintentional access to Key Vault from Azure services, advanced access policies must be configured only as required.\n\n**Remediation**\nRemove any advanced policies that are not required using the command: Remove-AzKeyVaultAccessPolicy -VaultName ‘{VaultName}’ -ResourceGroupName ‘{ResourceGroupName}’ -EnabledForDeployment -EnabledForTemplateDeployment -EnabledForDiskEncryption. Refer: https://docs.microsoft.com/en-us/powershell/module/az.keyvault/Remove-AzKeyVaultAccessPolicy\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/controls/keyVault_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "keyVault_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.keyvault/functions/KeyVault_Firewall.js: -------------------------------------------------------------------------------- 1 | 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | 4 | //AzNodeRest 5 | module.exports = async function (item) { 6 | 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | 10 | if ( item?.properties?.networkAcls){ 11 | returnObject.isHealthy=true 12 | } 13 | 14 | returnObject.metadata = {networkAcls:item?.properties?.networkAcls || "no network ACL's"} 15 | //console.log(stashOrig) 16 | 17 | return returnObject 18 | 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /providers/microsoft.keyvault/functions/Keyvault_ReviewAdvancedAccessPolicies.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | //console.log(stashOrig) 10 | returnObject.isHealthy=true 11 | const templatePolicies = Object.keys(item?.properties).filter((key) =>key.match('enabledFor') && item.properties[key] == true).map(key => `${key}:${item.properties[key]}` ) 12 | console.log(templatePolicies) 13 | 14 | if (templatePolicies.length > 0) { 15 | returnObject.isHealthy = false 16 | } 17 | returnObject.metadata= templatePolicies 18 | 19 | return returnObject 20 | 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /providers/microsoft.keyvault/functions/keyVault_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { diagReview } = require("../../../plugins/nodeSrc/confirmDiag") 5 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 6 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | 12 | let returnObject = new returnObjectInit(item, __filename.split('/').pop()) 13 | try { 14 | //third argument "requireAll" means that all of the categories need to be enabled, default is that single category is required 15 | let diag = await diagReview(item, ['AuditEvent', 'allLogs']) 16 | returnObject.metadata = { 17 | diagnostics:JSON.stringify(diag) 18 | } 19 | returnObject.isHealthy=diag.isHealthy 20 | return returnObject 21 | } catch (error) { 22 | 23 | returnObject.metadata = error 24 | returnObject.isHealthy="manual" 25 | return returnObject 26 | 27 | } 28 | 29 | 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.logic/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2016-10-01"} -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_ActionsAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_Connections", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_Authorization.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_Authorization", 3 | "Category": "Access", 4 | "Description": "Consider authorization of HTTP triggers with AAD instead of passwords (SAS key)" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_ConnectionAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_Connections", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_ContentRestrictions.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_ContentRestrictions", 3 | "Category": "Access", 4 | "Description": "Ensure content restrictions are enabled if Logic App processes sensitive or regulated data, or when you want to ensure RBAC readers cant see data" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_InBoundRestrictions.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_ContentRestrictions", 3 | "Category": "Network", 4 | "Description": "Ensure IP restrictions are enabled when possible" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_ManagedIdentity.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_ManagedIdentity", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_WorkFlows.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_WorkFlows", 3 | "Category": "Data", 4 | "Description": "Review workflow results" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/controls/LogicApps_runHistory.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_runHistory", 3 | "Category": "Data", 4 | "Description": "Review workflow history for sensitive contents such as secrets and authentication keys" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_ActionsAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | 10 | let {properties} = item 11 | let auth = [] 12 | if (properties?.definition?.actions) { 13 | enumAuthKey(properties?.definition?.actions,auth) 14 | 15 | 16 | } 17 | 18 | if (auth.length == 0) { 19 | returnObject.isHealthy="notApplicable" 20 | } else { 21 | returnObject.isHealthy="review" 22 | } 23 | 24 | returnObject.metadata={auth} 25 | 26 | return returnObject 27 | 28 | } 29 | 30 | function enumAuthKey (v,mp) { 31 | 32 | if (typeof(v) === "object" && v !== null) { 33 | //console.log(v) 34 | if (v.hasOwnProperty('authentication')) { 35 | let hasManagedIdentity = JSON.stringify(v).toLowerCase().match('managed')?.input 36 | mp.push({authOptions:v,hasManagedIdentity}) 37 | } 38 | 39 | Object.keys(v).map(s => { 40 | enumAuthKey(v[s],mp) 41 | }) 42 | 43 | } 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_Authorization.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | //console.log(stashOrig) 9 | if (!item?.id.match('microsoft.logic/workflows')) { 10 | returnObject.metadata = JSON.stringify(item.properties?.accessControl) 11 | returnObject.isHealthy="notApplicable" 12 | return returnObject 13 | } 14 | 15 | returnObject.metadata = {} 16 | returnObject.isHealthy="notApplicable" 17 | 18 | if (item?.properties?.definition?.triggers?.manual?.kind.toLowerCase() == "http" && !item.properties?.accessControl?.triggers?.openAuthenticationPolicies) { 19 | let pol = item.properties?.accessControl?.triggers?.openAuthenticationPolicies 20 | let trig = item?.properties?.definition?.triggers 21 | returnObject.metadata = {pol,trig} 22 | returnObject.isHealthy=false 23 | 24 | } 25 | 26 | 27 | if (item?.properties?.definition?.triggers?.manual?.kind.toLowerCase() == "http" && item.properties?.accessControl?.triggers?.openAuthenticationPolicies) { 28 | let pol = item.properties?.accessControl?.triggers?.openAuthenticationPolicies 29 | let trig = item?.properties?.definition?.triggers 30 | returnObject.metadata = {pol,trig} 31 | returnObject.isHealthy=true 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | return returnObject 40 | 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_ConnectionAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | 10 | let {properties} = item 11 | let auth = [] 12 | if (properties?.parameters.toString().length > 5) { 13 | enumAuthKey(properties?.parameters,auth) 14 | 15 | 16 | } 17 | 18 | if (auth.length == 0) { 19 | returnObject.isHealthy="notApplicable" 20 | } else { 21 | returnObject.isHealthy="review" 22 | } 23 | 24 | returnObject.metadata={auth} 25 | 26 | return returnObject 27 | 28 | } 29 | 30 | function enumAuthKey (v,mp) { 31 | 32 | if (typeof(v) === "object") { 33 | 34 | if (v.hasOwnProperty('authentication')) { 35 | let hasManagedIdentity = JSON.stringify(v).toLowerCase().match('managed')?.input 36 | mp.push({authOptions:v,hasManagedIdentity}) 37 | } 38 | 39 | Object.keys(v).map(s => { 40 | enumAuthKey(v[s],mp) 41 | }) 42 | 43 | } 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_ContentRestrictions.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (!item?.id.match('microsoft.logic/workflows')) { 12 | returnObject.metadata = item?.properties 13 | returnObject.isHealthy="notApplicable" 14 | return returnObject 15 | } 16 | 17 | var failedMessage = "no access controls for contents" 18 | var accessControls = item?.properties?.accessControl?.contents?.allowedCallerIpAddresses || failedMessage 19 | returnObject.isHealthy=false 20 | if ( accessControls !== failedMessage){ 21 | returnObject.isHealthy=true 22 | } 23 | 24 | 25 | returnObject.metadata = {accessControls} 26 | //console.log(stashOrig) 27 | 28 | return returnObject 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_InBoundRestrictions.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (!item?.id.match('microsoft.logic/workflows')) { 12 | returnObject.metadata = item?.properties 13 | returnObject.isHealthy="notApplicable" 14 | return returnObject 15 | } 16 | 17 | var failedMessage = "no access controls for actions or triggers" 18 | var accessControls = (item?.properties?.accessControl?.triggers || item?.properties?.accessControl?.actions ) || failedMessage 19 | returnObject.isHealthy=false 20 | if ( accessControls !== failedMessage){ 21 | returnObject.isHealthy=true 22 | 23 | if (item?.properties?.accessControl?.triggers?.allowedCallerIpAddresses?.length == 0 && item?.properties?.accessControl?.actions?.allowedCallerIpAddresses?.length == 0 ) { 24 | accessControls="Only Other Logic Apps" 25 | } 26 | } 27 | 28 | 29 | returnObject.metadata = {accessControls} 30 | //console.log(stashOrig) 31 | 32 | return returnObject 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_ManagedIdentity.js: -------------------------------------------------------------------------------- 1 | 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 4 | 5 | const { iterateMI } = require("../../../plugins/nodeSrc/miGeneral") 6 | 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | let skip = checkDoesItApply(item,returnObject) 12 | if (skip) { 13 | return skip 14 | } 15 | 16 | 17 | let identityList 18 | try {identityList = await iterateMI(item)} catch(err) { 19 | 20 | console.log(err) 21 | 22 | } 23 | 24 | if (identityList) { 25 | returnObject.isHealthy=true 26 | } 27 | 28 | returnObject.name = item.name 29 | returnObject.id = item.id 30 | returnObject.metadata = {identityList} 31 | 32 | } 33 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_WorkFlows.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (!item?.id.match('microsoft.logic/workflows')) { 12 | returnObject.metadata = item?.properties 13 | returnObject.isHealthy="notApplicable" 14 | return returnObject 15 | } 16 | 17 | var failedMessage = "no access controls for actions or triggers" 18 | 19 | returnObject.isHealthy=true 20 | 21 | let matchLikelySecrets = require('../../../plugins/other/wordlist.json').values.split(',').map(word => { 22 | srs = JSON.stringify(item.properties.definition).toLowerCase().match(word.toLowerCase()) 23 | // let srs2 = JSON.stringify(item.properties.definition).toLowerCase().match(new RegExp("\\?code",'g')) 24 | if (srs) { 25 | console.log() 26 | returnObject.isHealthy="review" 27 | } 28 | return srs 29 | }).filter(is => is !== null).map(s => `${s[0]}:${s.input.substring(s.index-30,s.index+30)}`) 30 | 31 | returnObject.metadata = {contents:JSON.stringify(item.properties.definition), matchLikelySecrets} 32 | //console.log(stashOrig) 33 | 34 | return returnObject 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /providers/microsoft.logic/functions/LogicApps_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('WorkflowRuntime","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.network/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-03-01"} -------------------------------------------------------------------------------- /providers/microsoft.network/.skip.json: -------------------------------------------------------------------------------- 1 | [ 2 | "microsoft.network/frontdoorwebapplicationfirewallpolicies", 3 | "microsoft.network/privatednszones", 4 | "microsoft.network/dnszones", 5 | "microsoft.network/localnetworkgateways", 6 | "microsoft.network/virtualnetworkgateways", 7 | "microsoft.network/networkwatchers", 8 | "microsoft.network/networkinterfaces", 9 | "microsoft.network/trafficmanagerprofiles" 10 | ] -------------------------------------------------------------------------------- /providers/microsoft.network/applicationgateways/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2019-09-01"} -------------------------------------------------------------------------------- /providers/microsoft.network/applicationgateways/controls/agw_waf.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "afd_waf", 3 | "Category": "Network", 4 | "Description": "Ensure Web Application Firewall is enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/applicationgateways/functions/agw_waf.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 11 | 12 | 13 | if (item?.properties.sku.match('WAF')) { 14 | returnObject.isHealthy=true 15 | } 16 | 17 | returnObject.metadata = {waf:item?.properties.sku} 18 | //console.log(stashOrig) 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /providers/microsoft.network/controls/pip_appliedNSG.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "network_publicIpAdvanced", 3 | "Category": "Network", 4 | "Description": "Review unrestricted public IP's" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/controls/pip_conf_old.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "network_publicIpAdvanced", 3 | "Category": "Network", 4 | "Description": "Review unrestricted public IP's" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/frontdoors/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-06-01"} -------------------------------------------------------------------------------- /providers/microsoft.network/frontdoors/controls/afd_waf.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "afd_waf", 3 | "Category": "Network", 4 | "Description": "Ensure Web Application Firewall is enabled" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/frontdoors/controls/afd_waf_mode.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "afd_waf_mode", 3 | "Category": "Network", 4 | "Description": "Ensure WAF is operating on prevention mode instead of detection mode. Detection mode should only be used initially to tune the rules of WAF - It's aim being to enable prevention mode as soon as possible " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/frontdoors/functions/afd_waf.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 2 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 3 | 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | 8 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 9 | 10 | 11 | let WAFEnabled = item.properties.frontendEndpoints.filter(s => s?.properties?.webApplicationFirewallPolicyLink?.id) 12 | .map(s =>s.properties.webApplicationFirewallPolicyLink ) || "no WAF" 13 | 14 | if (WAFEnabled.length >0) { 15 | returnObject.isHealthy = true 16 | } 17 | 18 | returnObject.metadata = {WAFEnabled} 19 | //console.log(stashOrig) 20 | 21 | return returnObject 22 | 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /providers/microsoft.network/frontdoors/functions/afd_waf_mode.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 11 | 12 | let WAFEnabled = item.properties.frontendEndpoints.filter(s => s?.properties?.webApplicationFirewallPolicyLink?.id) 13 | .map(s =>s.properties.webApplicationFirewallPolicyLink ) || "no WAF" 14 | 15 | if (WAFEnabled.length >0) { 16 | let mode = await AzNodeRest(WAFEnabled[0].id,'2020-11-01') 17 | var policySettings = mode.properties.policySettings 18 | 19 | if (policySettings.mode.toLowerCase() == "prevention") { 20 | returnObject.isHealthy = true 21 | } 22 | } 23 | 24 | returnObject.metadata = {res:item?.properties?.frontendEndpoints || {}} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /providers/microsoft.network/functions/disabled_pip_appliedNSG.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getAppliedNSG } = require("../../../plugins/nodeSrc/getEffectiveNSG") 6 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | //const { testConnection } = require("../../../test") 9 | 10 | //AzNodeRest 11 | module.exports = async function (item) { 12 | 13 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 14 | 15 | if (!item?.id.match('microsoft.network/publicipaddresses')) { 16 | returnObject.metadata = item?.properties 17 | returnObject.isHealthy="notApplicable" 18 | return returnObject 19 | } 20 | 21 | var {apiversion} = getProviderApiVersion(item.id) 22 | 23 | if (item?.properties?.ipConfiguration) { 24 | 25 | var attachment = item?.properties?.ipConfiguration.id.split('ipConfigurations')[0] 26 | 27 | 28 | var netset = await AzNodeRest(`${attachment}`,'2021-03-01') 29 | 30 | 31 | if (netset.id.match('networkInterfaces')) { 32 | 33 | const results = await getAppliedNSG(netset.id) 34 | 35 | returnObject.isHealthy = "manual" 36 | returnObject.metadata = {results} 37 | return returnObject 38 | } 39 | 40 | } 41 | 42 | returnObject.isHealthy = true 43 | returnObject.metadata = {results:item?.type} 44 | //console.log(stashOrig) 45 | 46 | return returnObject 47 | 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /providers/microsoft.network/publicipaddresses/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-03-01"} -------------------------------------------------------------------------------- /providers/microsoft.network/publicipaddresses/controls/pip_conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "pip_conf", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/virtualnetworks/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2022-01-01"} -------------------------------------------------------------------------------- /providers/microsoft.network/virtualnetworks/controls/vnet_peerings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "vnet_peerings", 3 | "Category": "Network", 4 | "Description": "Review virtual network peerings" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.network/virtualnetworks/functions/vnet_peerings.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item, __filename.split('/').pop()) 11 | 12 | 13 | if (item?.properties?.virtualNetworkPeerings == "") { 14 | returnObject.isHealthy = true 15 | returnObject.metadata = {result:"no peerings"} 16 | } 17 | else { 18 | returnObject.isHealthy = "review" 19 | returnObject.metadata = { peering:JSON.stringify(item?.properties?.virtualNetworkPeerings) } 20 | } 21 | 22 | //console.log(stashOrig) 23 | 24 | return returnObject 25 | 26 | } 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /providers/microsoft.relay/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2017-04-01"} -------------------------------------------------------------------------------- /providers/microsoft.relay/controls/relay_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "relay_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/controls/relay_hybridConnFirewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Network restrictions", 3 | "Category": "Network", 4 | "Description": "It is recommended to limit the callers of the service by IP addresses, when callers of the services are known" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/controls/relay_reviewConnectionEndpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "relay_reviewConnectionEndpoints", 3 | "Category": "Network", 4 | "Description": "Ensure Relay connection endpoints are cleaned up periodically, and require client authorization at all times. If possible restrict connections from the agent in network level \r\n [about Relays](https://docs.microsoft.com/en-us/azure/azure-relay/relay-what-is-it#hybrid-connections) " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/functions/relay_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | if (!item?.type == "microsoft.relay/namespaces") { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } 17 | 18 | 19 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 20 | 21 | try { 22 | var logs =JSON.stringify(diagnostics).match('HybridConnectionsEvent","categoryGroup":null,"enabled":true')[0] 23 | returnObject.isHealthy=true 24 | } catch (error) { 25 | console.log() 26 | } 27 | 28 | 29 | 30 | 31 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 32 | //console.log(stashOrig) 33 | 34 | return returnObject 35 | 36 | } 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /providers/microsoft.relay/functions/relay_hybridConnFirewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | if (!item?.type == "microsoft.relay/namespaces") { 11 | returnObject.metadata = item?.properties 12 | returnObject.isHealthy="notApplicable" 13 | return returnObject 14 | } 15 | 16 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 17 | //console.log(stashOrig) 18 | 19 | returnObject.isHealthy="manual" 20 | 21 | 22 | 23 | let {apiversion} = getProviderApiVersion(item.id) 24 | 25 | let {value:networkSettings} = await AzNodeRest(`${item.id}/networkrulesets/`,apiversion) 26 | 27 | if (networkSettings[0].properties?.ipRules.length == 0 && networkSettings[0].properties?.virtualNetworkRules.length == 0) { 28 | returnObject.isHealthy=false 29 | } 30 | 31 | returnObject.metadata={networkSettings} 32 | 33 | return returnObject 34 | 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /providers/microsoft.relay/functions/relay_reviewConnectionEndpoints.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | if (!item?.type == "microsoft.relay/namespaces") { 11 | returnObject.metadata = item?.properties 12 | returnObject.isHealthy="notApplicable" 13 | return returnObject 14 | } 15 | 16 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 17 | //console.log(stashOrig) 18 | 19 | returnObject.isHealthy="review" 20 | 21 | let {apiversion} = getProviderApiVersion(item.id) 22 | 23 | let {value:HybridConnections} = await AzNodeRest(`${item.id}/hybridConnections/`,apiversion) 24 | 25 | returnObject.metadata={HybridConnections} 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2017-04-01"} -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/controls/relay_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "relay_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/controls/relay_hybridConnFirewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Network restrictions", 3 | "Category": "Network", 4 | "Description": "It is recommended to limit the callers of the service by IP addresses, when callers of the services are known" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/controls/relay_new.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "relay_new", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/controls/relay_reviewConnectionEndpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "relay_reviewConnectionEndpoints", 3 | "Category": "Network", 4 | "Description": "Ensure Relay connection endpoints are cleaned up periodically, and require client authorization at all times. If possible restrict connections from the agent in network level \r\n [about Relays](https://docs.microsoft.com/en-us/azure/azure-relay/relay-what-is-it#hybrid-connections) " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/functions/relay_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | 13 | /* 14 | // relay changed to namespace based folder lookup 15 | if (!item?.type == "microsoft.relay/namespaces") { 16 | returnObject.metadata = item?.properties 17 | returnObject.isHealthy="notApplicable" 18 | return returnObject 19 | } */ 20 | 21 | 22 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 23 | 24 | try { 25 | var logs =JSON.stringify(diagnostics).match('HybridConnectionsEvent","categoryGroup":null,"enabled":true')[0] 26 | returnObject.isHealthy=true 27 | } catch (error) { 28 | console.log() 29 | } 30 | 31 | 32 | 33 | 34 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 35 | //console.log(stashOrig) 36 | 37 | return returnObject 38 | 39 | } 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/functions/relay_hybridConnFirewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | 8 | module.exports = async function (item) { 9 | 10 | /* 11 | // relay changed to namespace based folder lookup 12 | if (!item?.type == "microsoft.relay/namespaces") { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } */ 17 | 18 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 19 | //console.log(stashOrig) 20 | 21 | returnObject.isHealthy="manual" 22 | 23 | 24 | 25 | let {apiversion} = getProviderApiVersion(item.id) 26 | 27 | let {value:networkSettings} = await AzNodeRest(`${item.id}/networkrulesets/`,apiversion) 28 | 29 | if (networkSettings[0].properties?.ipRules.length == 0 && networkSettings[0].properties?.virtualNetworkRules.length == 0) { 30 | returnObject.isHealthy=false 31 | } 32 | 33 | returnObject.metadata={networkSettings} 34 | 35 | return returnObject 36 | 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/functions/relay_new.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 11 | 12 | 13 | returnObject.metadata = {item} 14 | //console.log(stashOrig) 15 | 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /providers/microsoft.relay/namespaces/functions/relay_reviewConnectionEndpoints.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | /* 11 | // relay changed to namespace based folder lookup 12 | if (!item?.type == "microsoft.relay/namespaces") { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } */ 17 | 18 | 19 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 20 | //console.log(stashOrig) 21 | 22 | returnObject.isHealthy="review" 23 | 24 | let {apiversion} = getProviderApiVersion(item.id) 25 | 26 | let {value:HybridConnections} = await AzNodeRest(`${item.id}/hybridConnections/`,apiversion) 27 | 28 | returnObject.metadata={HybridConnections} 29 | 30 | return returnObject 31 | 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /providers/microsoft.servicebus/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2021-06-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.servicebus/controls/sb_avoidNamespacePolicies.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_avoidNamespacePolicies", 3 | "Category": "Data", 4 | "Description": "\n\nAZSK Migrated: Service bus clients (senders/receivers) must not use 'namespace' level access policies\n\n*A 'namespace' level access policy provides access to all Queues/Topics in a namespace. However, using an access policy at entity (Queue/Topic) level provides access only to the specific entity. Thus using the latter is inline with the principle of least privilege.*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicebus/controls/sb_diagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sb_diagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the service" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicebus/controls/sb_disableLocalAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sb_disableLocalAuth", 3 | "Category": "Access", 4 | "Description": "\n[source](https://docs.microsoft.com/en-us/azure/service-bus-messaging/policy-reference)\n\n*Disabling local authentication methods improves security by ensuring that Azure Service Bus namespaces exclusively require Azure Active Directory identities for authentication. Learn more at: https://aka.ms/disablelocalauth-sb* " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicebus/controls/sb_firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_avoidNamespacePolicies", 3 | "Category": "Network", 4 | "Description": "Enable network restrictions If consumers of service can be identified by static network conditions" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicebus/controls/sb_useAzureRBACforDataAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "eh_useAzureRBACforDataAccess", 3 | "Category": "Access", 4 | "Description": "\n\nThis is direct description taken from:\n[source](https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-shared-access-signature\\#what-are-shared-access-signatures)\n\n\n\nAzure Service Bus supports authorizing access to a Service Bus namespace\nand its entities using Azure Active Directory (Azure AD). Authorizing\nusers or applications using OAuth 2.0 token returned by Azure AD\nprovides superior security and ease of use over shared access signatures\n(SAS). With Azure AD, there is no need to store the tokens in your code\nand risk potential security vulnerabilities.\n\nMicrosoft recommends using Azure AD with your Azure Service Bus\napplications when possible. For more information, see the following\narticles:\n\n- [Authenticate and authorize an application with Azure Active\n Directory to access Azure Service Bus\n entities](authenticate-application).\n- [Authenticate a managed identity with Azure Active Directory to\n access Azure Service Bus\n resources](service-bus-managed-service-identity)\n\nYou can disable local or SAS key authentication for a Service Bus\nnamespace and allow only Azure AD authentication. For step-by-step\ninstructions, see [Disable local\nauthentication](disable-local-authentication)\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicebus/functions/sb_avoidNamespacePolicies.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { azNodeRestRef } = require("../../../plugins/nodeSrc/nodeRestRef") 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | //console.log(stashOrig) 10 | 11 | let {value} = await azNodeRestRef(`${item.id}/authorizationRules`,'2017-04-01') 12 | let nameSpaceLevel = value.filter(s => !s.name.match('RootManageSharedAccessKey')) 13 | 14 | if (!nameSpaceLevel.length > 0) { 15 | returnObject.isHealthy=true 16 | } 17 | 18 | returnObject.metadata=nameSpaceLevel 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.servicebus/functions/sb_diagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 13 | 14 | try { 15 | var logs =JSON.stringify(diagnostics).match('OperationalLogs","categoryGroup":null,"enabled":true')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | 22 | 23 | 24 | returnObject.metadata = {logs:logs || {diagnostics:JSON.stringify(diagnostics)} || "no logs"} 25 | //console.log(stashOrig) 26 | 27 | return returnObject 28 | 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.servicebus/functions/sb_disableLocalAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | 5 | //AzNodeRest 6 | module.exports = async function (item) { 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | if (item?.properties?.disableLocalAuth == true) { 10 | returnObject.isHealthy = true 11 | } 12 | 13 | returnObject.metadata=item.properties 14 | return returnObject 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /providers/microsoft.servicebus/functions/sb_firewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { azNodeRestRef } = require("../../../plugins/nodeSrc/nodeRestRef") 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | //console.log(stashOrig) 10 | 11 | let {properties:networkSettings} = await azNodeRestRef(`${item.id}/networkrulesets/default`,'2021-06-01-preview') 12 | returnObject.isHealthy=true 13 | 14 | if (networkSettings.ipRules.length == 0 && networkSettings.virtualNetworkRules.length == 0) { 15 | returnObject.isHealthy=false 16 | } 17 | 18 | returnObject.metadata=networkSettings 19 | 20 | return returnObject 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.servicefabric/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2020-12-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.servicefabric/controls/sf_ClusterProtectionLevel.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sf_ClusterProtectionLevel", 3 | "Category": "Data", 4 | "Description": "AZ Policy
Service Fabric provides three levels of protection (None, Sign and EncryptAndSign) for node-to-node communication using a primary cluster certificate. Set the protection level to ensure that all node-to-node messages are encrypted and digitally signed" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.servicefabric/functions/sf_ClusterProtectionLevel.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | 14 | try { 15 | var EncryptAndSign =JSON.stringify(item?.properties?.fabricSettings).match('EncryptAndSign')[0] 16 | returnObject.isHealthy=true 17 | } catch (error) { 18 | console.log() 19 | } 20 | 21 | returnObject.metadata = {result:EncryptAndSign || "failed"} 22 | //console.log(stashOrig) 23 | 24 | return returnObject 25 | 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /providers/microsoft.sql/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2020-11-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_Firewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Network", 4 | "Description": "\n“Allow Azure services and resources to access this server” setting for SQL allows a trivial bypass for Azure firewall. Essentially meaning, that if attacker gets the SQL connection string, the protection by network rules does very little to protect from the attack. \n- Unfortunately many Azure Services rely on this setting to access SQL. Consider using this setting only if managed identities are in the ACL for SQL\n \n![image](https://user-images.githubusercontent.com/58001986/156122091-4e9f7fbb-54eb-4f4c-9c67-cf5234cc8ce1.png)\n\n\n\n" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_adminQuery.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sql_adminQuery", 3 | "Category": "EXAMPLE: Authentication strength, Attack surface reduction", 4 | "Description": "Queries the server for certain operations" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_listDatabases.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sql_listDatabases", 3 | "Category": "Review", 4 | "Description": "EXAMPLE: Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_minTLS.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sql_minTLS", 3 | "Category": "Network", 4 | "Description": "Ensure TLS version is enforced to be 1.2" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_pe.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sql_pe", 3 | "Category": "Network", 4 | "Description": "Disable SQL public network connectivity if private endpoints are used" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/controls/sql_vulnAssessment.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sql_vulnAssessment", 3 | "Category": "Protection", 4 | "Description": "This item uses the Azure Defender For Cloud results for various SQL checks. Having items failure in this item does not indicate major problems, but rather points out audit items created by MDC" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.sql/functions/disabled_sql_listDatabases.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | //https://docs.microsoft.com/en-us/rest/api/sql/2021-02-01-preview/databases/list-by-server 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | 14 | if (item?.id.match('databases')) { 15 | returnObject.metadata = item?.properties 16 | returnObject.isHealthy="notApplicable" 17 | return returnObject 18 | } 19 | 20 | var {apiversion} = getProviderApiVersion(item.id) 21 | 22 | item = await AzNodeRest(`${item.id}/firewallRules/`,apiversion) 23 | 24 | var is = item?.value.filter((rules) => rules.name == "AllowAllWindowsAzureIps") 25 | 26 | if ( is.length > 0){ 27 | returnObject.isHealthy=false 28 | } 29 | 30 | returnObject.metadata = {item} 31 | //console.log(stashOrig) 32 | 33 | return returnObject 34 | 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /providers/microsoft.sql/functions/sql_Firewall.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 11 | 12 | if (item?.id.match('databases')) { 13 | returnObject.metadata = item?.properties 14 | returnObject.isHealthy="notApplicable" 15 | return returnObject 16 | } 17 | 18 | returnObject.isHealthy=true 19 | 20 | var {apiversion} = getProviderApiVersion(item.id) 21 | 22 | let fw = await AzNodeRest(`${item.id}/firewallRules/`,apiversion) 23 | 24 | var is = fw?.value.filter((rules) => rules.name == "AllowAllWindowsAzureIps") 25 | 26 | if ( is.length > 0 || fw?.value.length == 0 ){ 27 | returnObject.isHealthy=false 28 | } 29 | 30 | if (item?.properties?.publicNetworkAccess !== "Enabled" && item.properties?.privateEndpointConnections.length > 0) { 31 | returnObject.isHealthy = true 32 | } 33 | 34 | returnObject.metadata = {fw} 35 | //console.log(stashOrig) 36 | 37 | return returnObject 38 | 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /providers/microsoft.sql/functions/sql_minTLS.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | if (item?.id.match('databases')) { 14 | returnObject.metadata = item?.properties 15 | returnObject.isHealthy="notApplicable" 16 | return returnObject 17 | } 18 | 19 | if (item?.properties?.minimalTlsVersion == "1.2" ) { 20 | returnObject.isHealthy=true 21 | } 22 | 23 | returnObject.metadata = {minimalTlsVersion:item?.properties?.minimalTlsVersion} 24 | //console.log(stashOrig) 25 | 26 | return returnObject 27 | 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /providers/microsoft.sql/functions/sql_pe.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | returnObject.isHealthy = true 14 | 15 | if (item?.id.match('databases')) { 16 | returnObject.metadata = item?.properties 17 | returnObject.isHealthy="notApplicable" 18 | return returnObject 19 | } 20 | 21 | if (item?.properties?.publicNetworkAccess == "Enabled" && item.properties?.privateEndpointConnections.length > 0) { 22 | returnObject.isHealthy = false 23 | } 24 | 25 | returnObject.metadata = {publicNetworkAccess:item?.properties?.publicNetworkAccess, privateEndpointConnections: item.properties?.privateEndpointConnections } 26 | //console.log(stashOrig) 27 | 28 | return returnObject 29 | 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /providers/microsoft.storage/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2022-05-01"} -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_BlobDiagnostics.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Storage_BlobDiagnostics", 3 | "Category": "Logs", 4 | "Description": "Ensure important blobs are logged for access" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_ClosePublicIfPE.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Storage_ClosePublicIfPE", 3 | "Category": "Network", 4 | "Description": "If storage account is configured to use private endpoints, it is in most cases recommended to disable public access, to ensure that only private connectivity is available" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_EnableFirewall.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Storage_EnableFirewall", 3 | "Category": "Network", 4 | "Description": "Review storage for network bypasses, and non IP limited access" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_PublicAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review storage for public access" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_hasPublicBlobs.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "sd2", 3 | "Category": "Access", 4 | "Description": "Review storage for public access" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/Storage_httpsOnly.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Storage_httpsOnly", 3 | "Category": "Encryption", 4 | "Description": "Ensure storage access requires HTTPS" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/storage_aadAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "storage_aadAuth", 3 | "Category": "Access", 4 | "Description": "Prefer AAD based authentication with storage accoutnts" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/storage_cloudShell.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "storage_cloudShell", 3 | "Category": "Data", 4 | "Description": "Identify Cloud Shells that can possibly persist credentials, and are not monitored (logging is not enabled) for unauthorized access " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/storage_crossTenantReplication.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "storage_crossTenantReplication", 3 | "Category": "Data", 4 | "Description": "As per Azure Policy Description: \"By default, users can configure object replication with a source storage account in one Azure AD tenant and a destination account in a different tenant. It is a security concern because customer's data can be replicated to a storage account that is owned by the customer. By setting allowCrossTenantReplication to false, objects replication can be configured only if both source and destination accounts are in the same Azure AD tenant.\" " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/storage_denyKeyBasedAuthentication.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "storage_denyPublicAccessSetting", 3 | "Category": "Access", 4 | "Description": "This setting denies key based access on storage account level" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/controls/storage_denyPublicAccessSetting.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "storage_denyPublicAccessSetting", 3 | "Category": "Access", 4 | "Description": "This setting denies public blob access on storage account level" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/Storage_BlobDiagnostics.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | let diagnostics = await AzNodeRest(`${item.id}/blobServices/default/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 12 | 13 | 14 | if ( diagnostics.value.length > 0){ 15 | returnObject.isHealthy=true 16 | } 17 | 18 | returnObject.metadata = {BlobDiagnostics: diagnostics.value.length > 0|| ["No diagnostic settings enabled"]} 19 | //console.log(stashOrig) 20 | 21 | return returnObject 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/Storage_ClosePublicIfPE.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 11 | 12 | returnObject.isHealthy="not applicable" 13 | var is 14 | if (item.properties?.privateEndpointConnections?.length > 0) { 15 | 16 | is = (item.properties.networkAcls.ipRules.length > 0 || item.properties.networkAcls.virtualNetworkRules.length > 0) || undefined 17 | 18 | if (is == undefined){ 19 | returnObject.isHealthy=false 20 | } else { 21 | returnObject.isHealthy=true 22 | } 23 | 24 | 25 | } 26 | 27 | 28 | 29 | returnObject.metadata = {networkAcls: item.properties?.networkAcls, privateEndpointConnections: item.properties?.privateEndpointConnections} 30 | //console.log(stashOrig) 31 | 32 | return returnObject 33 | 34 | } 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/Storage_EnableFirewall.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | 12 | var is = (item.properties.networkAcls.ipRules.length > 0 || item.properties.networkAcls.virtualNetworkRules.length > 0) || undefined 13 | 14 | if (is == undefined){ 15 | returnObject.isHealthy=false 16 | } else { 17 | returnObject.isHealthy=true 18 | } 19 | 20 | 21 | returnObject.metadata = item.properties.networkAcls 22 | //console.log(stashOrig) 23 | 24 | return returnObject 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/Storage_PublicAccess.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | var waitT = require('util').promisify(setTimeout) 5 | const {argv} = require('yargs') 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | ; 10 | 11 | var {apiversion} = getProviderApiVersion(item.id) 12 | 13 | var returnObject ={} 14 | returnObject.fileName = __filename.split('/').pop() 15 | returnObject.name = item.name 16 | returnObject.id = item.id 17 | 18 | 19 | console.log('waiting before enumeration of containers, to avoid throttling') 20 | 21 | if (!argv.SkipStorageThrottling) { 22 | await waitT(3000) 23 | } 24 | 25 | item = await AzNodeRest(`${item.id}/blobServices/default/containers?`,apiversion) 26 | 27 | returnObject.isHealthy=true 28 | if (item?.value.length > 0) { 29 | 30 | 31 | var isPublic = item.value.filter((container) => container.properties.publicAccess == "Blob" || container.properties.publicAccess == "Container").map(item => `${item.name} - Public:${item.properties.publicAccess}`) 32 | 33 | if (isPublic.length > 0) { 34 | console.log(isPublic) 35 | returnObject.isHealthy=false 36 | } 37 | 38 | 39 | } 40 | 41 | 42 | returnObject.metadata = {count:item.value.length, Public:isPublic || [] } 43 | 44 | return returnObject 45 | 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/Storage_httpsOnly.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | 12 | var is = item?.properties?.supportsHttpsTrafficOnly == false 13 | 14 | if (is){ 15 | returnObject.isHealthy=false 16 | } else { 17 | returnObject.isHealthy=true 18 | } 19 | 20 | 21 | returnObject.metadata = {supportsHttpsTrafficOnly:item?.properties?.supportsHttpsTrafficOnly} 22 | //console.log(stashOrig) 23 | 24 | return returnObject 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/storage_aadAuth.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 5 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 6 | const { checkRoles } = require("../../../plugins/nodeSrc/listRoles") 7 | const { azNodeRestRef } = require("../../../plugins/nodeSrc/nodeRestRef") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | //console.log(stashOrig) 13 | let scope = item.id.split('/') 14 | 15 | 16 | // get top level AAD authorization 17 | let {roles} =await checkRoles(scope[2]) 18 | let AzureRbacRoles = roles.filter(sd => sd?.properties?.roleName.match('Storage') && !sd?.properties?.roleName.match('Classic') ).map(d => { 19 | return { 20 | id:d.name, 21 | display:d.properties.roleName 22 | } 23 | }) || [] 24 | 25 | 26 | let assignments = JSON.stringify(await AzNodeRest(`${item.id}/providers/Microsoft.Authorization/roleAssignments?roleAssignments?$filter=atScope()`,"2021-04-01-preview")) 27 | 28 | 29 | const AADRolesInUseTopLevel = AzureRbacRoles.filter(c => assignments.match(c.id)) 30 | if (AADRolesInUseTopLevel.length > 0) { 31 | returnObject.isHealthy=true 32 | returnObject.metadata = AADRolesInUseTopLevel 33 | return returnObject 34 | } 35 | 36 | returnObject.metadata={AADRolesInUseTopLevel} 37 | 38 | return returnObject 39 | 40 | } -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/storage_cloudShell.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | //console.log(stashOrig) 11 | 12 | returnObject.isHealthy=true 13 | let diagnostics 14 | 15 | if (JSON.stringify(item?.tags).match('azure-cloud-shell')) { 16 | 17 | diagnostics= await AzNodeRest(`${item.id}/fileServices/default/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 18 | 19 | returnObject.isHealthy="review" 20 | 21 | if ( diagnostics?.value.length == 0){ 22 | returnObject.isHealthy=false 23 | } 24 | 25 | } 26 | 27 | returnObject.metadata={tags:item?.tags || "no tags",diagnostics} 28 | 29 | return returnObject 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/storage_crossTenantReplication.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 7 | 8 | //AzNodeRest 9 | module.exports = async function (item) { 10 | 11 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 12 | 13 | 14 | /* 15 | 16 | // add this part if you plan to add policies to report 17 | 18 | let {apiversion} = getProviderApiVersion(item.id) */ 19 | 20 | /* let objectReplicationPolicies = await AzNodeRest(`${item.id}/objectReplicationPolicies/`,apiversion) */ 21 | 22 | 23 | if ( item?.allowCrossTenantReplication !== false){ 24 | returnObject.isHealthy=false 25 | } 26 | 27 | returnObject.metadata = {allowCrossTenantReplication:item?.allowCrossTenantReplication || true} 28 | //console.log(stashOrig) 29 | 30 | return returnObject 31 | 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/storage_denyKeyBasedAuthentication.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (item?.properties?.allowSharedKeyAccess == false) { 12 | returnObject.isHealthy=true 13 | } 14 | 15 | 16 | returnObject.metadata = {allowSharedKeyAccess:item?.properties?.allowSharedKeyAccess} 17 | //console.log(stashOrig) 18 | 19 | return returnObject 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /providers/microsoft.storage/functions/storage_denyPublicAccessSetting.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | if (item?.properties?.allowBlobPublicAccess == false) { 12 | returnObject.isHealthy=true 13 | } 14 | 15 | 16 | returnObject.metadata = {allowBlobPublicAccess:item?.properties?.allowBlobPublicAccess} 17 | //console.log(stashOrig) 18 | 19 | return returnObject 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /providers/microsoft.web/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2020-06-01"} -------------------------------------------------------------------------------- /providers/microsoft.web/.skip.json: -------------------------------------------------------------------------------- 1 | ["microsoft.web/certificates","microsoft.web/serverfarms"] -------------------------------------------------------------------------------- /providers/microsoft.web/connections/.apiVersion.json: -------------------------------------------------------------------------------- 1 | {"apiversion":"2018-07-01-preview"} -------------------------------------------------------------------------------- /providers/microsoft.web/connections/controls/LogicApps_Connections.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_Connections_1", 3 | "Category": "Data", 4 | "Description": "When possible try to use Azure AD Backed connections instead of local authentication options" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/connections/functions/LogicApps_Connections.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { AzNodeRest } = require("../../../../plugins/nodeSrc/east") 4 | const { returnObjectInit } = require("../../../../plugins/nodeSrc/returnObjectInit") 5 | 6 | 7 | //AzNodeRest 8 | module.exports = async function (item) { 9 | 10 | let returnObject = new returnObjectInit (item,__filename.split('/').pop()) 11 | 12 | 13 | returnObject.metadata = {item} 14 | //console.log(stashOrig) 15 | returnObject.isHealthy="review" 16 | return returnObject 17 | 18 | } 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /providers/microsoft.web/controls/WebApp_LogicAppsWorkflows.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "LogicApps_WorkFlows", 3 | "Category": "Data", 4 | "Description": "Review workflow results" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/WebApp_VnetRouteAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "WebApp_VnetRouteAll", 3 | "Category": "Network", 4 | "Description": "It is important to enable VNET_ROUTE_ALL setting In environments where apps are configured to use dedicated applicance for egress connectivity. Otherwise egress will use Azure App Services own egress IP " 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/WebApp_minTLS.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "WebApp_minTLS", 3 | "Category": "Network", 4 | "Description": "Ensure TLS level is set above 1.0" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/WebSites_DiagnosticSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "WebSites_DiagnosticSettings", 3 | "Category": "Logs", 4 | "Description": "Ensure logs are enabled for the webapp" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/Webapp_SCM_admin.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "AppSVC_SCM", 3 | "Category": "Access", 4 | "Description": "\n\n**Source**: [MS Control](https://docs.microsoft.com/en-us/azure/app-service/deploy-configure-credentials?tabs=cli#disable-basic-authentication)\n\n*Some organizations need to meet security requirements and would rather disable access via FTP or WebDeploy. This way, the organization's members can only access its App Services through APIs that are controlled by Azure Active Directory (Azure AD).*\n\n**From Azure Policy**\n\n*Disable local authentication methods for SCM sites so that your App Services exclusively require Azure Active Directory identities for authentication. Learn more at: https://aka.ms/app-service-disable-basic-auth*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/aadAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\r\n FuncAuthentication \r\n", 3 | "Category": "Access", 4 | "Description": "\r\n Enabling authentication with Azure AD allows strong authentication and RBAC to be evaluated for authorized requests" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/fn_runtimeVersion.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "fn_runtimeVersion", 3 | "Category": "Access", 4 | "Description": "Function versions 2,3 have reached EOL on 2022. \r\n. Recommendation is to update to supported function runtime version https://learn.microsoft.com/en-us/azure/azure-functions/functions-versions" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/httpsSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\r\n HTTPSOnly\r\n", 3 | "Category": "Encryption", 4 | "Description": "\r\nConsider using only HTTPS based connections towards azure functions" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/managedIdentity.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\r\nmanagedIdentity\r\n", 3 | "Category": "Access", 4 | "Description": "\r\n Ensure The Service calls downstream resources with managed identity" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/networkRestrictions.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Network restrictions", 3 | "Category": "Network", 4 | "Description": "It is recommended to limit the callers of the service by IP addresses, when callers of the services are known" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/remoteDebugging.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "Network restrictions", 3 | "Category": "Access", 4 | "Description": "\r\n**Disable remote debugging**\r\nSource [MS](https://docs.microsoft.com/en-us/azure/azure-functions/security-concepts#disable-remote-debugging)\r\n\r\n\r\n*Make sure that remote debugging is disabled, except when you are actively debugging your functions. You can disable remote debugging in the General Settings tab of your function app Configuration in the portal.*" 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/controls/webApp_ftpStatus.json: -------------------------------------------------------------------------------- 1 | { 2 | "ControlId": "\r\nftpStatus\r\n", 3 | "Category": "Access", 4 | "Description": "\r\nFTP is rarely used in Azure Web Apps / Functions." 5 | } -------------------------------------------------------------------------------- /providers/microsoft.web/functions/WebApp_VnetRouteAll.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 4 | //AzNodeRest 5 | module.exports = async function (item) { 6 | 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | var skip = checkDoesItApply(item,returnObject) 10 | if (skip) { 11 | return skip 12 | } 13 | 14 | 15 | let config = await AzNodeRest(`${item.id}/config/web`,"2020-06-01") 16 | 17 | if ( config.properties?.vnetName ) { 18 | 19 | if (config.properties?.vnetRouteAllEnabled == "review") { 20 | returnObject.isHealthy=false 21 | } 22 | 23 | if (config.properties?.vnetRouteAllEnabled == true) { 24 | returnObject.isHealthy=true 25 | } 26 | 27 | 28 | } 29 | else { 30 | returnObject.isHealthy="not applicable" 31 | } 32 | 33 | returnObject.metadata = {vnetRouteAllEnabled:config.properties?.vnetRouteAllEnabled, vnetName: config.properties?.vnetName} 34 | 35 | return returnObject 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/WebApp_minTLS.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 4 | const { getAzWebAppConfig } = require("../../../plugins/nodeSrc/webAppConfig") 5 | 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | 10 | let configs = await getAzWebAppConfig(item) 11 | //let configs = await AzNodeRest(`${item.id}/config/web?`,'2018-11-01') 12 | 13 | var minTls = configs?.properties?.minTlsVersion 14 | 15 | if (minTls == "1.2") { 16 | returnObject.isHealthy=true 17 | } 18 | 19 | 20 | //console.log(stashOrig) 21 | returnObject.metadata={minTls} 22 | return returnObject 23 | 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/WebSites_DiagnosticSettings.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | 14 | var skip = checkDoesItApply(item,returnObject) 15 | if (skip) { 16 | return skip 17 | } 18 | var {apiversion} = getProviderApiVersion(item.id) 19 | 20 | if (item?.id.match('sqli') ) { 21 | console.log() 22 | } 23 | 24 | const diagnostics = await AzNodeRest(`${item.id}/providers/microsoft.insights/diagnosticSettings?`,'2021-05-01-preview') 25 | 26 | try { 27 | var logs =JSON.stringify(diagnostics).match('FunctionAppLogs\",\"categoryGroup\":null,\"enabled\":true')[0] 28 | returnObject.isHealthy=true 29 | } catch (error) { 30 | console.log() 31 | } 32 | 33 | try { 34 | var appServicelogs =JSON.stringify(diagnostics).match('AppServiceAuditLogs\",\"categoryGroup\":null,\"enabled\":true')[0] 35 | returnObject.isHealthy=true 36 | } catch (error) { 37 | console.log() 38 | } 39 | 40 | 41 | 42 | 43 | returnObject.metadata = {logs:logs || {appServicelogs,diagnostics:JSON.stringify(diagnostics)} || "no logs"} 44 | //console.log(stashOrig) 45 | 46 | return returnObject 47 | 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/Webapp_SCM_admin.js: -------------------------------------------------------------------------------- 1 | 2 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 3 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 4 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 5 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 6 | //AzNodeRest 7 | module.exports = async function (item) { 8 | //https://docs.microsoft.com/en-us/rest/api/appservice/web-apps/get-scm-allowed 9 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 10 | 11 | var {apiversion} = getProviderApiVersion(item.id) 12 | 13 | var skip = checkDoesItApply(item,returnObject) 14 | if (skip) { 15 | return skip 16 | } 17 | 18 | returnObject.isHealthy=true 19 | 20 | item = await AzNodeRest(`${item.id}/basicPublishingCredentialsPolicies/scm/`,apiversion) 21 | 22 | var is = item?.properties?.allow == true || undefined 23 | 24 | if ( is){ 25 | returnObject.isHealthy=false 26 | is = `${item?.type} ${JSON.stringify(item?.properties)}` 27 | } 28 | 29 | returnObject.metadata = {basicAuthEnabled:is || ['basic auth is disabled']} 30 | //console.log(stashOrig) 31 | 32 | return returnObject 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/fn_runtimeVersion.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 5 | const { getProviderApiVersion } = require("../../../plugins/nodeSrc/getProvider") 6 | const { checkDoesItApply, checkDoesItApplyFn } = require("../../../plugins/nodeSrc/microsoftwebhelper") 7 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 8 | 9 | //AzNodeRest 10 | module.exports = async function (item) { 11 | 12 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 13 | 14 | 15 | let skip = checkDoesItApplyFn(item,returnObject) 16 | if (skip) { 17 | return skip 18 | } 19 | 20 | let data = await AzNodeRest(`${item.id}/host/default/properties/status`,'2018-11-01') 21 | 22 | 23 | if (!data?.properties?.version?.split('.')[0].match('4')) { 24 | 25 | returnObject.isHealthy=false 26 | } 27 | 28 | returnObject.metadata = {runtime:data?.properties?.version} 29 | //console.log(stashOrig) 30 | 31 | return returnObject 32 | 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/httpsSettings.js: -------------------------------------------------------------------------------- 1 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | 4 | module.exports = async function (item) { 5 | 6 | 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | 10 | var skip = checkDoesItApply(item,returnObject) 11 | if (skip) { 12 | return skip 13 | } 14 | 15 | var keyToCheck = item?.properties?.httpsOnly 16 | 17 | returnObject.isHealthy=false 18 | if (keyToCheck) { 19 | returnObject.isHealthy=true} 20 | 21 | 22 | returnObject.metadata = {httpsOnly:keyToCheck || ["Plain HTTP is allowed"]} 23 | 24 | 25 | return returnObject 26 | } 27 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/managedIdentity.js: -------------------------------------------------------------------------------- 1 | 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 4 | const { iterateMI } = require("../../../plugins/nodeSrc/miGeneral") 5 | 6 | module.exports = async function (item) { 7 | 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | 10 | let skip = checkDoesItApply(item,returnObject) 11 | if (skip) { 12 | return skip 13 | } 14 | 15 | 16 | let identityList 17 | try {identityList = await iterateMI(item)} catch(err) { 18 | 19 | console.log(err) 20 | 21 | } 22 | 23 | if (identityList) { 24 | returnObject.isHealthy=true 25 | } 26 | 27 | returnObject.name = item.name 28 | returnObject.id = item.id 29 | returnObject.metadata = {identityList} 30 | 31 | return returnObject 32 | } 33 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/networkRestrictions.js: -------------------------------------------------------------------------------- 1 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 4 | //AzNodeRest 5 | module.exports = async function (item) { 6 | 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | var skip = checkDoesItApply(item,returnObject) 10 | if (skip) { 11 | return skip 12 | } 13 | 14 | 15 | var item = await AzNodeRest(`${item.id}/config/web`,"2020-06-01") 16 | 17 | if ( JSON.stringify(item.properties?.ipSecurityRestrictions).match('Allow all')) { 18 | //console.log('got this for network rest', item.properties?.ipSecurityRestrictions) 19 | returnObject.isHealthy=false 20 | } 21 | else { 22 | returnObject.isHealthy=true 23 | } 24 | 25 | returnObject.metadata = { 26 | ipSecurityRestrictions: item.properties?.ipSecurityRestrictions, 27 | scmIpSecurityRestrictions:item.properties?.scmIpSecurityRestrictions, 28 | 29 | } 30 | 31 | 32 | return returnObject 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/remoteDebugging.js: -------------------------------------------------------------------------------- 1 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 2 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 3 | 4 | module.exports = async function (item) { 5 | 6 | 7 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 8 | 9 | /* require() */ 10 | 11 | var skip = checkDoesItApply(item,returnObject) 12 | if (skip) { 13 | return skip 14 | } 15 | 16 | var keyToCheck = item?.properties?.httpsOnly 17 | 18 | returnObject.isHealthy=false 19 | if (keyToCheck) { 20 | returnObject.isHealthy=true} 21 | 22 | 23 | returnObject.metadata = {keyToCheck} 24 | 25 | 26 | return returnObject 27 | } 28 | -------------------------------------------------------------------------------- /providers/microsoft.web/functions/webApp_ftpStatus.js: -------------------------------------------------------------------------------- 1 | const { returnObjectInit } = require("../../../plugins/nodeSrc/returnObjectInit") 2 | const { checkDoesItApply } = require("../../../plugins/nodeSrc/microsoftwebhelper") 3 | const { AzNodeRest } = require("../../../plugins/nodeSrc/east") 4 | const { getAzWebAppConfig } = require("../../../plugins/nodeSrc/webAppConfig") 5 | module.exports = async function (item) { 6 | 7 | 8 | let returnObject = new returnObjectInit(item,__filename.split('/').pop()) 9 | 10 | 11 | let configs = await getAzWebAppConfig(item) 12 | //let configs = await AzNodeRest(`${item.id}/config/web?`,'2018-11-01') 13 | 14 | var ftpsState = configs?.properties?.ftpsState 15 | 16 | if (ftpsState == "Disabled") { 17 | returnObject.isHealthy=true 18 | keyToCheck="FTP is not allowed" 19 | } 20 | 21 | returnObject.metadata = {ftpsState:configs?.properties?.ftpsState} 22 | 23 | 24 | return returnObject 25 | } 26 | -------------------------------------------------------------------------------- /sh/deleteToken.sh: -------------------------------------------------------------------------------- 1 | 2 | rm plugins/session/graphToken.json 3 | rm plugins/session/sessionToken.json 4 | rm plugins/session/aadToken.json 5 | rm plugins/session/iamToken.json 6 | rm plugins/session/graphToken2.json -------------------------------------------------------------------------------- /sh/initForCustomer2.sh: -------------------------------------------------------------------------------- 1 | 2 | { # try 3 | 4 | az account clear 5 | rm plugins/session/graphToken.json 6 | rm plugins/session/sessionToken.json 7 | rm plugins/session/aadToken.json 8 | rm plugins/session/iamToken.json 9 | #save your output 10 | 11 | } || { # catch 12 | echo "no tokens to destroy" 13 | } 14 | 15 | 16 | git config --global user.name "Your Name" 17 | git checkout --orphan temp; git add .; git commit -m "s" -------------------------------------------------------------------------------- /sh/initForuse.sh: -------------------------------------------------------------------------------- 1 | 2 | ## setup pandoc for reporting 3 | 4 | wget "https://github.com/jgm/pandoc/releases/download/2.17.1.1/pandoc-2.17.1.1-linux-amd64.tar.gz"; 5 | tar xvzf "pandoc-2.17.1.1-linux-amd64.tar.gz" --strip-components 1 -C ~ 6 | 7 | # Clone the project 8 | 9 | git clone https://github.com/jsa2/EAST --branch preview 10 | 11 | cd EAST; 12 | npm install 13 | 14 | -------------------------------------------------------------------------------- /sh/updatePolicyDef.sh: -------------------------------------------------------------------------------- 1 | az policy definition list > plugins/other/defaultPolicydef.json -------------------------------------------------------------------------------- /templatehelpers/custom/_AADDefaultSettings.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | 11 | it.metadata.results.map(s => { 12 | 13 | 14 | details+="\r\n" 15 | details+="\r\n" 16 | details += `###### ${s.refInfo}` 17 | details+="\r\n" 18 | details+="\r\n" 19 | details+= `Count of principals in role ${s.value.length}` 20 | details+="\r\n" 21 | var sd = beautify(JSON.stringify(s.value),{ indent_size: 2, space_in_empty_paren: true }) 22 | details+="\r\n" 23 | details+=`\`\`\`json \r\n ${sd} \r\n \`\`\`\r\n` 24 | 25 | }) 26 | 27 | 28 | 29 | return details 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /templatehelpers/custom/_AAD_Privileged_SPN.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | details+="\r\n" 11 | details+="\r\n" 12 | 13 | it.metadata.forEach(s => { 14 | details+="\r\n" 15 | details+= ` \`\`\`${s.replace('#microsoft.graph.servicePrincipal','SPN')} \`\`\` ` 16 | details+="\r\n" 17 | 18 | }) 19 | 20 | 21 | 22 | return details 23 | 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /templatehelpers/custom/_ADF_Linked_Services.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+="\r\n" 8 | details+="\r\n" 9 | 10 | it.metadata.list.sort((a,b) => { 11 | if (a.svc.match('"safeCredential":false') ) { 12 | return -1; 13 | } 14 | }) 15 | 16 | it.metadata.list.map(s => { 17 | let ps = JSON.parse(s.svc) 18 | var lnk1 = ps.name.toLowerCase() 19 | details+="\r\n" 20 | details+="\r\n" 21 | details+=`

${ps.name}

` 22 | details+="\r\n" 23 | details+="\r\n" 24 | var sd = beautify(JSON.stringify(ps),{ indent_size: 2, space_in_empty_paren: true }) 25 | details+="\r\n" 26 | details+=`\`\`\`json \r\n ${sd} \r\n \`\`\`\r\n` 27 | 28 | 29 | 30 | }) 31 | 32 | 33 | 34 | return details 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /templatehelpers/custom/_ADF_pipeline_svc_mapping.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | 11 | it.metadata.pipelines.map(pi => { 12 | pi.LinkdSvcToActivity.map(link => { 13 | details +=`${link.pipeLine}` 14 | details+="\r\n" 15 | details+="\r\n" 16 | details +=` - [${link.links}](#${link.links})`.toLowerCase() 17 | details+="\r\n" 18 | details+="\r\n" 19 | 20 | }) 21 | }) 22 | 23 | 24 | 25 | return details 26 | 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /templatehelpers/custom/_aad_caEval.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | 11 | Object.keys(it.metadata).map(s => { 12 | 13 | 14 | details+="\r\n" 15 | details+="\r\n" 16 | details += `**Policy ${s}**` 17 | details+="\r\n" 18 | details+="\r\n" 19 | let sf = JSON.parse(it.metadata[s]?.details) 20 | var sd = beautify(JSON.stringify(sf),{ indent_size: 2, space_in_empty_paren: true }) 21 | details+="\r\n" 22 | details+=`\`\`\`json \r\n ${sd} \r\n \`\`\`\r\n` 23 | 24 | }) 25 | 26 | 27 | 28 | return details 29 | 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /templatehelpers/custom/_adminsCa.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | 11 | it.metadata.results.map(s => { 12 | 13 | 14 | details+="\r\n" 15 | details+="\r\n" 16 | details += `###### ${s.refInfo}` 17 | details+="\r\n" 18 | details+="\r\n" 19 | details+= `Count of principals in role ${s.value.length}` 20 | details+="\r\n" 21 | var sd = beautify(JSON.stringify(s.value),{ indent_size: 2, space_in_empty_paren: true }) 22 | details+="\r\n" 23 | details+=`\`\`\`json \r\n ${sd} \r\n \`\`\`\r\n` 24 | 25 | }) 26 | 27 | 28 | 29 | return details 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /templatehelpers/custom/_sql_vulnAssessment.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify').js 2 | 3 | module.exports = function (it,control) { 4 | let details = '' 5 | var lnk=`metadata_${it.name}_${control.group}`.toLowerCase() 6 | details+=`

${it.name}_${control.group}

` 7 | details+=`` 8 | details+="\r\n" 9 | details+="\r\n" 10 | it.metadata.assessments.sort((a,b) => { 11 | //console.log(a) 12 | if (a.status.toLowerCase() > b.status.toLowerCase()) { 13 | return -1; 14 | } else { 15 | return 0 16 | } 17 | }) 18 | 19 | it.metadata.assessments.forEach(s => { 20 | 21 | details+="\r\n" 22 | details+="\r\n" 23 | details+= `**Status: ${s.status} DB: ${s.database} : ${s.id}**` 24 | details+="\r\n" 25 | details+="\r\n" 26 | details+= `Description: ${s.description} \r\n Impact: ${s.impact}` 27 | details+="\r\n" 28 | details+="\r\n" 29 | 30 | }) 31 | 32 | 33 | 34 | return details 35 | 36 | } 37 | 38 | 39 | --------------------------------------------------------------------------------