module/ConfigurationProvider/ControlConfigurations/Services/AppService.json
{
"FeatureName": "AppService", "Reference": "aka.ms/azsktcp/appservice", "IsMaintenanceMode": false, "Controls": [ { "ControlID": "Azure_AppService_AuthZ_Grant_Min_RBAC_Access", "Description": "All users/identities must be granted minimum required permissions using Role Based Access Control (RBAC)", "Id": "AppService110", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckRBACAccess", "Rationale": "Granting minimum access by leveraging RBAC feature ensures that users are granted just enough permissions to perform their tasks. This minimizes exposure of the resources in case of user/service account compromise.", "Recommendation": "Remove any excessive privileges granted on the App Service. Run command: Remove-AzRoleAssignment -SignInName '<SignInName>' -Scope '<Scope>' RoleDefinitionName '<RoleDefinitionName>'. Run 'Get-Help Remove-AzRoleAssignment -full' for more help.", "Tags": [ "SDL", "TCP", "Automated", "AuthZ", "RBAC", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Use_CNAME_With_SSL", "Description": "Custom domain with SSL binding must be configured for App Service", "Id": "AppService120", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceCustomDomainWithSSLConfig", "DisplayName": "Custom domain with SSL binding must be configured for App Service", "Category": "Encrypt data in transit", "ControlRequirements": "Data must be encrypted in transit and at rest", "Rationale": "Use of custom domain protects a web application from common attacks such as phishing, session hijacking and other DNS-related attacks.", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Custom Domains and follow the steps mentioned to configure a custom domain. Run command 'New-AzWebAppSSLBinding' to enable the SSL binding for your custom domain. Run 'Get-Help New-AzWebAppSSLBinding -full' for more help.", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Weekly" ], "Enabled": true, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_AuthN_Use_AAD_for_Client_AuthN", "Description": "App Service must authenticate users using Azure Active Directory backed credentials", "Id": "AppService130", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceADAuthentication", "AssessmentName": "", "PolicyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/95bccee9-a7f8-4bec-9ee9-62c3473701fc", "Rationale": "Using the native enterprise directory for authentication ensures that there is a built-in high level of assurance in the user identity established for subsequent access control.All Enterprise subscriptions are automatically associated with their enterprise directory (xxx.onmicrosoft.com) and users in the native directory are trusted for authentication to enterprise subscriptions.", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Authentication/Authorization --> turn on 'App Service Authentication' --> Click on 'Azure Active Directory' under Authentication Providers to configure the AAD authentication. There will be a list of options to choose from under 'Action to take when request is not authenticated'. Please make sure that this value is not set to 'Allow Anonymous requests (no action)'. Note: If you are implementing this control via code, then you can attest to the same and mark this as passed. Note: In case of Functions apps, AAD authentication is required only for 'Http Trigger' functions.", "Tags": [ "SDL", "TCP", "Automated", "AuthN", "OwnerAccess", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Deploy_Dont_Use_Publish_Profiles", "Description": "Publish profile credentials must not be used for App Service deployment", "Id": "AppService140", "ControlSeverity": "High", "Automated": "No", "MethodName": "", "Rationale": "Publish profile of App Services contains deployment and FTP credentials. There are 2 risks with this. First, the credentials can get easily leaked during the various workflows involving the publish profile. Secondly, use of public profiles weakens auditability of deployment actions.", "Recommendation": "No predefined role should be present in the App Service and all the custom roles must have all 'publishxml' operations added as the Non Actions, e.g. 'microsoft.web/sites/publishxml/read'. Refer https://docs.microsoft.com/en-us/azure/app-service/faq-deployment#i-am-just-getting-started-with-app-service-web-apps-how-do-i-publish-my-code for exploring ways to securely deploy app service.", "Tags": [ "SDL", "TCP", "Manual", "Deploy", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_AuthZ_Trigger_Url_AuthN", "Description": "Trigger URL for the App Service Web Job must require authentication", "Id": "AppService150", "ControlSeverity": "High", "Automated": "No", "MethodName": "", "DisplayName": "Web Job trigger URL for App Service Web Jobs must require authentication", "Category": "Authentication must be enabled on all user accounts and services", "ControlRequirements": "Access to data, networks, services, utilities, tools, and applications must be controlled by authentication and authorization mechanisms", "Rationale": "Scheduled WebJobs can be triggered by specific scheduled time or by triggered URL. WebJob triggered URL can be authenticated by AAD authentication (bearer token) or by App Services deployment credentials. Since its not recommended to use publish profiles, WebJob triggered URL must be authenticated by AAD authentication.", "Recommendation": "Use bearer tokens and AAD-based authentication to in the trigger.", "Tags": [ "SDL", "Information", "Manual", "AuthZ", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Encrypt_In_Transit_Webhook", "Description": "The webhook used for a Web Job must encrypt sensitive data in transit", "Id": "AppService180", "ControlSeverity": "High", "Automated": "No", "MethodName": "", "DisplayName": "The webhook used for a Web Job must encrypt sensitive data in transit", "Category": "Encrypt data in transit", "ControlRequirements": "Data must be encrypted in transit and at rest", "Rationale": "Use of HTTPS ensures server/service authentication and protects data in transit from network layer man-in-the-middle, eavesdropping, session-hijacking attacks.", "Recommendation": "Encryption in transit in the context of webhooks can be achieved by using HTTPS URLs.", "Tags": [ "SDL", "Information", "Manual", "DP", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Store_Secrets_in_Key_Vault", "Description": "All App Service secrets should be stored in Key Vault", "Id": "AppService190", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Rationale": "Keeping secrets such as DB connection strings, passwords, keys, etc. in clear text can lead to easy compromise at various avenues during an application's lifecycle. Storing them in a key vault ensures that they are protected at rest.", "Recommendation": "Refer https://azure.microsoft.com/en-in/documentation/articles/key-vault-get-started/ for configuring Key Vault and storing secrets.", "Tags": [ "SDL", "Best Practice", "Manual", "DP", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Deploy_Use_Notification_Hub", "Description": "App Service should use Notification Hub for push notification (instead of directly using Push Notification Service)", "Id": "AppService200", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Rationale": "Notification Hub provides a better mechanism to manage the keys related Push Notification Systems (PNS).", "Recommendation": "Refer https://docs.microsoft.com/en-us/azure/notification-hubs/ for details on configuring Notification Hub for push notifications.", "Tags": [ "SDL", "Best Practice", "Manual", "Deploy", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Config_Disable_Remote_Debugging", "Description": "Remote debugging must be turned off for App Service", "Id": "AppService210", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceRemoteDebuggingConfiguration", "DisplayName": "Remote debugging should be turned off for Web Applications", "Category": "Remote debugging must be disabled", "ControlRequirements": "Remote debugging is disabled by default", "Rationale": "Remote debugging requires inbound ports to be opened on App Service. These ports become easy targets for compromise from various internet-based attacks.", "Recommendation": "To disable remote debugging on default 'Production' slot: Go to Azure Portal --> your App Service --> Settings --> Configuration --> General Settings --> Remote Debugging (Under Debugging) --> Click on 'OFF' --> Save. To disable remote debugging on any non-production slot: Go to Azure Portal --> your App Service --> Deployment --> Deployment slots --> Select slot --> Settings --> Configuration --> General Settings --> Remote Debugging (Under Debugging) --> Click on 'OFF' --> Save", "Tags": [ "SDL", "TCP", "Automated", "Config", "AppService", "FunctionApp", "Baseline", "Daily", "CSEOPilotP1", "CSEOPilotSub" ], "ControlEvaluationDetails": { "RequiredProperties": [ "RemoteDebuggingEnabled", "SiteConfig", "DeploymentSlots", "SlotRemoteDebuggingEnabled", "SlotSiteConfig" ] }, "Enabled": true, "CustomTags": [ "Windows", "Linux", "CSEOBaseline", "MSD", "TenantBaseline", "Prod", "CSEOPilot", "Wave8", "SN:AppSvc_Debug" ] }, { "ControlID": "Azure_AppService_Config_Disable_Remote_Debugging_Trial", "Description": "[Trial] Remote debugging must be turned off for App Service", "Id": "AppService500", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceRemoteDebuggingConfigurationTrial", "ControlScanSource": "MDCAndReader", "DisplayName": "[Trial] Remote debugging should be turned off for Web Applications", "Category": "Remote debugging must be disabled", "ControlRequirements": "Remote debugging is disabled by default", "Rationale": "Remote debugging requires inbound ports to be opened on App Service. These ports become easy targets for compromise from various internet-based attacks.", "Recommendation": "To disable remote debugging on default 'Production' slot: Go to Azure Portal --> your App Service --> Settings --> Configuration --> General Settings --> Remote Debugging (Under Debugging) --> Click on 'OFF' --> Save. To disable remote debugging on any non-production slot: Go to Azure Portal --> your App Service --> Deployment --> Deployment slots --> Select slot --> Settings --> Configuration --> General Settings --> Remote Debugging (Under Debugging) --> Click on 'OFF' --> Save", "Tags": [ "SDL", "TCP", "Automated", "Config", "AppService", "FunctionApp", "Baseline", "Daily" ], "AssessmentProperties": { "AssessmentNames": [ "093c685b-56dd-13a3-8ed5-887a001837a2", "64b8637e-4e1d-76a9-0fc9-c1e487a97ed8" ] }, "ControlEvaluationDetails": { "RequiredProperties": [ "RemoteDebuggingEnabled", "SiteConfig", "DeploymentSlots", "SlotRemoteDebuggingEnabled", "SlotSiteConfig" ] }, "Enabled": true, "CustomTags": [ "Daily", "Trial" ], "ControlSettings": { "FallBackToReaderLogic": true } }, { "ControlID": "Azure_AppService_Config_Disable_Web_Sockets", "Description": "Web Sockets should be disabled for App Service", "Id": "AppService220", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceWebSocketsConfiguration", "DisplayName": "Web Sockets should be disabled for App Service", "ControlRequirements": "Data must be encrypted in transit and at rest", "Category": "Encrypt data in transit", "Rationale": "WebSockets protocol (WS) is vulnerable to different types of security attacks. Usage of Web Sockets within web applications has to be carefully reviewed.", "Recommendation": "To disable Web Sockets on default 'Production' slot: Run command 'Set-AzWebApp -Name '<WebAppName>' -ResourceGroupName '<RGName>' -WebSocketsEnabled `$false'. Run 'Get-Help Set-AzWebApp -full' for more help. To disable Web Sockets on any non-production slot: Run command 'Set-AzWebAppSlot -ResourceGroupName '<RGName>' -Name '<WebAppName>' -Slot '<SlotName>' -WebSocketsEnabled `$false' Refer: https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md#websockets", "Tags": [ "SDL", "Best Practice", "Automated", "Config", "AppService", "FunctionApp", "Baseline", "Weekly", "CSEOPilotSub" ], "ControlEvaluationDetails": { "RequiredProperties": [ "WebSocketsEnabled", "SiteConfig", "DeploymentSlots", "SlotWebSocketsEnabled", "SlotSiteConfig" ] }, "Enabled": true, "CustomTags": [ "Windows", "Linux", "CSEOBaseline", "CSEOPilot" ] }, { "ControlID": "Azure_AppService_BCDR_Use_AlwaysOn", "Description": "'Always On' should be configured for App Service", "Id": "AppService230", "ControlSeverity": "Medium", "Automated": "Yes", "ControlScanSource": "Reader", "MethodName": "CheckAppServiceAlwaysOnConfiguration", "DisplayName": "'Always On' should be configured for App Service", "Category": "Reader role access to all subscription and resources", "ControlRequirements": "Security team visibility into all Microsoft assets", "Rationale": "By default, websites are unloaded if they have been idle for some period of time. However, this may not be ideal for 'high availability' requirements. Configuring 'Always On' can help prevent app services from getting timed out.", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Configuration --> General Settings --> Always On --> Click on 'ON'.", "Tags": [ "SDL", "Best Practice", "Automated", "BCDR", "AppService", "Baseline", "Weekly" ], "Enabled": true, "ControlSettings": { "ApplicableAppServiceKinds": [ "app" ] }, "ControlEvaluationDetails": { "RequiredProperties": [ "AppServiceKind", "AlwaysOn" ] }, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Deploy_Use_Latest_Version", "Description": "The latest version of .NET framework version should be used for App Service", "Id": "AppService240", "ControlSeverity": "Low", "Automated": "Yes", "MethodName": "CheckAppServiceDotNetFrameworkVersion", "Rationale": "Running on older .Net versions could mean you are not using latest security classes. Usage of such old classes and types can make your application vulnerable.", "Recommendation": "Run command 'Set-AzWebApp -Name '<WebAppName>' -ResourceGroupName '<RGName>' -NetFrameworkVersion 'v4.7''. Run 'Get-Help Set-AzWebApp -full' for more help.", "Tags": [ "SDL", "Best Practice", "Automated", "Deploy", "AppService", "FunctionApp" ], "Enabled": false, "FixControl": { "FixMethodName": "SetLatestDotNetVersion", "FixControlImpact": "Medium" }, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Deploy_Use_ARM_Template", "Description": "Deployment of App Service should be done using ARM template", "Id": "AppService260", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Rationale": "Deployment using ARM template is more secure than using publish profiles. This is because the former uses user/SPN credentials which can be protected better than publish profiles and provide a better audit trail of deployment activity.", "Recommendation": "Use an ARM Template to ensure fully repeatable and secured configuration of a deployment. Refer https://azure.microsoft.com/en-gb/resources/templates/ to get sample quickstart templates.", "Tags": [ "SDL", "Best Practice", "Manual", "Deploy", "AppService", "FunctionApp" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_BCDR_Use_Multiple_Instances", "Description": "App Service must be deployed on a minimum of two instances to ensure availability", "Id": "AppService270", "ControlSeverity": "Medium", "Automated": "Yes", "ControlScanSource": "Reader", "MethodName": "CheckAppServiceInstanceCount", "DisplayName": "App Service must be deployed on a minimum of two instances to ensure availability", "Category": "Reader role access to all subscription and resources", "ControlRequirements": "Security team visibility into all Microsoft assets", "Rationale": "App Service deployed on multiple instances ensures that the App Service remains available even if an instance is down.", "Recommendation": "Run command 'Set-AzAppServicePlan -Name '<AppServicePlanName>' -ResourceGroupName '<RGName>' -NumberofWorkers '<NumberofInstances>''. Run 'Get-Help Set-AzAppServicePlan -full' for more help.", "Tags": [ "SDL", "TCP", "Automated", "BCDR", "AppService", "Baseline", "Weekly" ], "Enabled": true, "ControlSettings": { "MinimumRequiredInstances": 2, "ApplicableAppServiceKinds": [ "app" ] }, "ControlEvaluationDetails": { "RequiredProperties": [ "AppServiceKind", "AppServicePlan" ] }, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_BCDR_Use_App_Backup", "Description": "Backup feature must be configured to backup data for App Service", "Id": "AppService280", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceBackupConfiguration", "Rationale": "Enabling backup on App Service ensures that there is always a previous snapshot of App Service data that can be leveraged towards recovery scenarios.", "Recommendation": "Run command 'Edit-AzWebAppBackupConfiguration -FrequencyInterval '1' -FrequencyUnit 'Day' -RetentionPeriodInDays '<0 or 365>' -StartTime '<TimeLessThanOrEqualToCurrentTime>' -Name '<WebAppName>' -ResourceGroupName '<RGName>' -StorageAccountUrl '<StorageAccountUrl>' -KeepAtLeastOneBackup'. Run 'Get-Help Edit-AzWebAppBackupConfiguration -full' for more help.", "Tags": [ "SDL", "Best Practice", "Automated", "BCDR", "OwnerAccess", "AppService" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Audit_Enable_Logging_and_Monitoring", "Description": "Auditing and Monitoring must be enabled for App Service", "Id": "AppService290", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceDiagnosticLogsConfiguration", "DisplayName": "Monitoring must be enabled for App Service", "Category": "Monitoring must be enabled", "ControlRequirements": "Monitoring and auditing must be enabled and correctly configured according to prescribed organizational guidance", "AssessmentName": "", "PolicyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/b607c5de-e7d9-4eee-9e5c-83f1bcee4fa0", "Rationale": "Auditing enables log collection of important system events pertinent to security. Regular monitoring of audit logs can help to detect any suspicious and malicious activity early and respond in a timely manner.", "Recommendation": "To enable monitoring on default 'Production' slot: Run command 'Set-AzWebApp -Name '<WebAppName>' -ResourceGroupName '<RGName>' -DetailedErrorLoggingEnabled `$true -HttpLoggingEnabled `$true -RequestTracingEnabled `$true'. Run 'Get-Help Set-AzWebApp -full' for more help. To enable monitoring on any non-production slot: Run command 'Set-AzWebAppSlot -ResourceGroupName '<RGName>' -Name '<WebAppName>' -Slot '<SlotName>' -DetailedErrorLoggingEnabled `$true -HttpLoggingEnabled `$true -RequestTracingEnabled `$true'", "Tags": [ "SDL", "TCP", "Automated", "Audit", "AppService", "FunctionApp", "Baseline", "Weekly", "ExcludedControl" ], "ControlEvaluationDetails": { "RequiredProperties": [ "AuditAndLogging", "SiteConfig", "DeploymentSlots", "SlotAuditAndLogging", "SlotSiteConfig" ] }, "Enabled": true, "FixControl": { "FixMethodName": "EnableLogging", "FixControlImpact": "Low" }, "PolicyDefinitionGuid": "752c6934-9bcc-4749-b004-655e676ae2ac", "PolicyDefnResourceIdSuffix": "/config/web", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_BCDR_Configure_Auto_Healing", "Description": "Auto healing should be configured for App Service", "Id": "AppService300", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Rationale": "With the use of Auto-Healing, a website can automatically recover from long running/blocked states. Auto-Healing enables automatic recycling of the worker process hosting your web application based on certain events. E.g. 1. When request count breaches a certain limit 2. When requests are running slower that expected 3. When an unexpected http status code is received X number of times 4. When the process consumes more than expected memory", "Recommendation": "Refer https://azure.microsoft.com/en-in/blog/auto-healing-windows-azure-web-sites/ for details on configuring auto healing.", "Tags": [ "SDL", "Best Practice", "Manual", "BCDR", "AppService" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Dont_Allow_HTTP_Access", "Description": "App Service must only be accessible over HTTPS", "Id": "AppService310", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceHttpsOnly", "DisplayName": "Use HTTPS for app services", "Category": "Encrypt data in transit", "ControlRequirements": "Data must be encrypted in transit and at rest", "PolicyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/a4af4a39-4135-47fb-b175-47fbdf85311d", "Rationale": "Use of HTTPS ensures server/service authentication and protects data in transit from network layer eavesdropping attacks.", "Recommendation": "To enable only https traffic on default 'Production' slot:Run command 'Set-AzWebApp -Name '<WebAppName>' -ResourceGroupName '<RGName>' -HttpsOnly `$true'. Run 'Get-Help Set-AzWebApp -full' for more help. To enable only https traffic on any non-production slot: Run command 'Set-AzWebAppSlot -ResourceGroupName '<RGName>' -Name '<WebAppName>' -Slot '<SlotName>' -HttpsOnly `$true'", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Daily", "CSEOPilotSub" ], "ControlEvaluationDetails": { "RequiredProperties": [ "HttpsEnabled", "DeploymentSlots", "SlotHttpsEnabled" ] }, "Enabled": true, "ControlScanSource": "MDCandReader", "AssessmentProperties": { "AssessmentNames": [ "cb0acdc6-0846-fd48-debe-9905af151b6d", "1b351b29-41ca-6df5-946c-c190a56be5fe", "bf82a334-13b6-ca57-ea75-096fc2ffce50" ], "AssessmentStatusMappings": [ { "AssessmentStatusCode": "NotApplicable", "EffectiveVerificationResult": "Failed", "AssessmentStatusCausePatterns": "(.)*OffByPolicy|Exempt(.)*", "AppendMessageToStatusReason": "Disabling or exempting the policy from getting evaluated is not recommended. The Control will be marked as Failed." } ] }, "ControlSettings": { "FallBackToReaderLogic": true }, "FixControl": { "FixMethodName": "EnableHttpsFlag", "FixControlImpact": "High" }, "PolicyDefinitionGuid": "a4af4a39-4135-47fb-b175-47fbdf85311d", "CustomTags": [ "Windows", "Linux", "TenantBaseline", "CSEOBaseline", "MSD", "Prod", "P2", "Wave5", "ShadowITActiveBaseline", "CSEOPilot", "SN:HTTPS" ] }, { "ControlID": "Azure_AppService_DP_Website_Load_Certificates_Not_All", "Description": "WEBSITE_LOAD_CERTIFICATES parameter must not be set to '*' (i.e. all) for App Service", "Id": "AppService320", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceLoadCertAppSettings", "Rationale": "Using '*' for this parameter means that all certificates will get uploaded to the VM running the website. This will most likely lead to abuse of the principle of least privilege as it is unlikely that the site needs access to all certificates at runtime.", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Configuration --> Application Settings --> Check for 'WEBSITE_LOAD_CERTIFICATES' key and make sure that value is not set to '*'. Instead choose the specific certificate that is required by the App Service. Refer https://msftplayground.com/2016/11/using-certificates-azure-app-services/ for more details.", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "OwnerAccess" ], "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Configure_Rotate_Keys_Fn", "Description": "Keys should be renewed after a regular interval", "Id": "AppService330", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Recommendation": "Refer https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook#authorization-keys for details on Host keys in Functions app.", "Tags": [ "SDL", "TCP", "Manual", "DP", "FunctionApp" ], "Enabled": false, "Rationale": "Periodic key/password rotation is a good security hygiene practice as, over time, it minimizes the likelihood of data loss/compromise which can arise from key theft/brute forcing/recovery attacks.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Dont_Share_HostKeys_Fn", "Description": "Host key access should not be shared with individual clients", "Id": "AppService340", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Recommendation": "Refer https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook#authorization-keys for details on Host keys in Functions app.", "Tags": [ "SDL", "TCP", "Manual", "DP", "FunctionApp" ], "Enabled": false, "Rationale": "Host Keys grant full access to all the functions within a function app. Not sharing this key with individual clients ensures that clients are granted just enough permissions to invoke a particular function", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Authz_Use_Function_Authorization_level_Fn", "Description": "Authorization level for HTTP Trigger function in a function app should be set to 'Function'", "Id": "AppService350", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckFunctionsAuthorizationLevel", "Recommendation": "Go to Azure Portal --> your Functions App --> your HTTP Trigger Function --> Integrate --> Change Authorization level.", "Tags": [ "SDL", "TCP", "Automated", "Config", "AuthZ", "OwnerAccess", "FunctionApp" ], "Enabled": false, "Rationale": "Use 'Function' authorization level to ensure that users with minimum of function keys should only be able to invoke the function. This is in accordance with the principle of least privilege.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_Configure_EditMode_ReadOnly_Fn", "Description": "Functions app edit mode should be set to Read Only", "Id": "AppService360", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckFunctionsEditMode", "Recommendation": "Go to Azure Portal --> your Functions App --> Functions app settings --> Function app edit mode --> Click on 'Read Only'.", "Tags": [ "SDL", "TCP", "Automated", "Config", "FunctionApp" ], "Enabled": false, "Rationale": "Using 'Read Only' mode ensures that source code is changes come in via a CICD pipeline and not directly through portal. This ensures that code changes are properly audited.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Use_Individual_FunctionKeys_Fn", "Description": "Different functions keys must be generated and shared with individual clients.", "Id": "AppService370", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Recommendation": "Go to Azure Portal --> your Functions App --> your Function --> Manage --> Add New Function Key.", "Tags": [ "SDL", "TCP", "Manual", "DP", "FunctionApp" ], "Enabled": false, "Rationale": "Different function keys for individual clients promotes separation of concerns. It also makes revocation easier to manage in the event of a compromise of one client.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Restrict_CORS_Access", "Description": "Ensure that CORS access is granted to a limited set of trusted origins.", "Id": "AppService380", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceCORSAllowed", "DisplayName": "Ensure that CORS access is granted to a limited set of trusted origins", "Category": "Deploy controls to restrict network traffic", "ControlRequirements": "Restrict network traffic flows", "Recommendation": "Go to Azure Portal --> your App Service --> API --> CORS --> Provide the specific domain names that should be allowed to make cross-origin calls. Note: No action is needed if you are not using CORS for your app.", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Weekly" ], "Enabled": true, "ControlEvaluationDetails": { "RequiredProperties": [ "SiteConfig", "SlotSiteConfig" ] }, "Rationale": "CORS enables applications running under one domain to access a resource under another domain. Using '*' (allow all) for CORS setting means that an application running under any domain can have access to your application's resources and data. Restricting allowed origins to the specific set that needs access aligns with the principle of least privilege.", "CustomTags": [ "Windows", "Linux" ], "ControlSettings": { "AllowAllSetting": "*" } }, { "ControlID": "Azure_AppService_Configure_Important_Alerts", "Description": "Alerts should be configured to track unauthorized access attempts for the AppService.", "Id": "AppService390", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Recommendation": "Go to Azure Portal --> your App Service --> Monitoring --> Alerts --> Add Alert. Set alert on metrics with name 'Http 403'(unauthorized response) and 'Http 401'(forbidden response).", "Tags": [ "SDL", "TCP", "Config", "AppService", "Manual" ], "Enabled": false, "Rationale": "Alert rules for unauthorized requests enable you to detect any suspicious and malicious activity early enough.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_AuthN_Use_Managed_Service_Identity", "Description": "Use Managed Service Identity (MSI) for accessing other AAD-protected resources from the app service.", "Id": "AppService400", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceMsiEnabled", "DisplayName": "Use Managed Service Identity (MSI) for accessing other AAD-protected resources from the app service", "Category": "Authentication must be enabled on all user accounts and services", "ControlRequirements": "Access to data, networks, services, utilities, tools, and applications must be controlled by authentication and authorization mechanisms", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Identity --> System assigned --> ON", "Tags": [ "SDL", "TCP", "Automated", "Config", "AppService", "FunctionApp", "Baseline", "Weekly" ], "Enabled": true, "Rationale": "Managed Service Identity (MSI) allows your app to easily access other AAD-protected resources such as Azure Key Vault. The identity is managed by the Azure platform and eliminates the need to provision/manage/rotate any secrets thus reducing the overall risk. ", "CustomTags": [ "Windows", "Linux" ], "ControlSettings": { "AllowedManagedServiceIdentityTypes": [ "SystemAssigned", "SystemAssigned, UserAssigned", "UserAssigned" ] } }, { "ControlID": "Azure_AppService_DP_Dont_Allow_HTTP_Access_Fn", "Description": "Function App must only be accessible over HTTPS", "Id": "AppService410", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckFunctionsAppHttpCertificateSSL", "Rationale": "Use of HTTPS ensures server/service authentication and protects data in transit from network layer eavesdropping attacks.", "Recommendation": "Run command 'Set-AzResource -ResourceName '<WebAppName>' -ResourceGroupName '<RGName>' -ResourceType 'Microsoft.Web/sites' -Properties @{httpsOnly='true'} -Force '. Run 'Get-Help Set-AzResource -full' for more help. Note:'HttpsOnly' is required only for 'Http Trigger' functions.", "Tags": [ "SDL", "TCP", "Automated", "DP", "OwnerAccess", "FunctionApp" ], "Enabled": false, "PolicyDefinitionGuid": "6d555dd1-86f2-4f1c-8ed7-5abae7c6cbab", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Use_Secure_TLS_Version", "Description": "Use approved version of TLS for the App Service", "Id": "AppService420", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceTLSVersion", "DisplayName": "Use Approved TLS Version in App Service", "Category": "Encrypt data in transit", "ControlRequirements": "Data must be encrypted in transit and at rest", "Recommendation": "To set required TLS version on default 'Production' slot: Go to Azure Portal --> your App Service --> Settings --> TLS/SSL --> Minimum TLS version --> set to org approved version (see status reason). To set required TLS version on any non-production slot: Go to Azure Portal --> your App Service --> Deployment --> Deployment slots --> Select slot --> Settings --> TLS/SSL --> Minimum TLS version --> set to org approved version (see status reason).", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Daily", "CSEOPilotSub" ], "ControlEvaluationDetails": { "RequiredProperties": [ "MinTlsVersion", "SiteConfig", "DeploymentSlots", "SlotMinTlsVersion", "SlotSiteConfig" ] }, "Enabled": true, "ControlScanSource": "MDCandReader", "AssessmentProperties": { "AssessmentNames": [ "15be5f3c-e0a4-c0fa-fbff-8e50339b4b22", "2a54c352-7ca4-4bae-ad46-47ecd9595bd2", "5a659d57-117d-bb18-65f6-54e51da1bb9b" ], "AssessmentStatusMappings": [ { "AssessmentStatusCode": "NotApplicable", "EffectiveVerificationResult": "Failed", "AssessmentStatusCausePatterns": "(.)*OffByPolicy|Exempt(.)*", "AppendMessageToStatusReason": "Disabling or exempting the policy from getting evaluated is not recommended. The Control will be marked as Failed." } ] }, "Rationale": "TLS provides privacy and data integrity between client and server. Using approved TLS version significantly reduces risks from security design issues and security bugs that may be present in older versions.", "ControlSettings": { "MinReqTLSVersion": "1.2", "FallBackToReaderLogic": true }, "CustomTags": [ "Windows", "Linux", "TenantBaseline", "CSEOBaseline", "MSD", "Prod", "P2", "Wave7", "ShadowITActiveBaseline", "CSEOPilot", "SN:AppSvc_TLS" ] }, { "ControlID": "Azure_AppService_DP_Verify_Installed_Extensions", "Description": "Extensions installed on a App Service should be carefully reviewed", "Id": "AppService430", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAppServiceInstalledExtensions", "Recommendation": "Go to Azure Portal --> your App Service --> Development Tools --> Extensions --> Verify installed extensions.", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp" ], "Enabled": false, "Rationale": "Each extension is something like a plugin that adds functionality to your App Service. Installing unknown/unverified extensions can be dangerous as some third party extensions may have vulnerabilities which introduce unnecessary avenues for attack.", "CustomTags": [ "Windows" ] }, { "ControlID": "Azure_AppService_AuthZ_Configure_IP_Restrictions", "Description": "Setup IP-based access restrictions for App Service if feasible", "Id": "AppService440", "ControlSeverity": "Medium", "Automated": "Yes", "ControlScanSource": "Reader", "MethodName": "CheckAppServiceAccessRestriction", "DisplayName": "Setup IP-based access restrictions for App Service if feasible", "Category": "Deploy controls to restrict network traffic", "ControlRequirements": "Restrict network traffic flows", "Recommendation": "Consider using IP-based access restrictions for App Service if feasible. Steps: Go to Azure Portal --> your App Service --> Networking --> Access Restrictions --> Configure Access Restrictions --> Add/Verify access restriction rule for app and scm site. For more information, refer: https://docs.microsoft.com/en-us/azure/app-service/app-service-ip-restrictions", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Weekly" ], "ControlEvaluationDetails": { "RequiredProperties": [ "SiteConfig", "IpSecurityRestrictions", "ScmIpSecurityRestrictions", "ScmIpSecurityRestrictionsUseMain" ] }, "Enabled": true, "Rationale": "Using the IP/VNet subnet rules-based access restriction ensures that access to the data or the service is restricted to a specific set of IPs. NOTE: While this control does provide an extra layer of access control protection, it may not always be feasible to implement in all scenarios.", "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Review_CORS_Request_Credential", "Description": "Review use of credentials in CORS request for App Service", "Id": "AppService450", "ControlSeverity": "Medium", "Automated": "Yes", "ControlScanSource": "Reader", "MethodName": "CheckAppServiceCORSCredential", "DisplayName": "Review use of credentials in CORS request for App Service", "Category": "Authentication must be enabled on all user accounts and services", "ControlRequirements": "Access to data, networks, services, utilities, tools, and applications must be controlled by authentication and authorization mechanisms", "Recommendation": "Go to Azure Portal --> your App Service --> API --> CORS --> Request Credentials --> Review if you need to enable 'Access-Control-Allow-Credentials'. Note: No action is needed if you are not using CORS for your app.", "Tags": [ "SDL", "TCP", "Automated", "DP", "AppService", "FunctionApp", "Baseline", "Weekly" ], "Enabled": true, "ControlEvaluationDetails": { "RequiredProperties": [ "SiteConfig", "SlotSiteConfig" ] }, "Rationale": "CORS enables applications running under one domain to access a resource under another domain. Allowing cross-origin credentials is a security risk. A website at another domain can send a signed-in user's credentials to the app on the user's behalf without the user's knowledge.", "CustomTags": [ "Windows" ] }, { "ControlID": "Azure_AppService_AuthN_Redirect_To_Login_Page", "Description": "App Service must be set to redirect unauthenticated requests to login page", "Id": "AppService460", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckAppServiceRootPageAuth", "Rationale": "Using the native enterprise directory for authentication ensures that there is a built-in high level of assurance in the user identity established for subsequent access control.All Enterprise subscriptions are automatically associated with their enterprise directory (xxx.onmicrosoft.com) and users in the native directory are trusted for authentication to enterprise subscriptions.", "Recommendation": "Go to Azure Portal --> your App Service --> Settings --> Authentication/Authorization --> turn on 'App Service Authentication' --> Click on 'Azure Active Directory' under Authentication Providers to configure the AAD authentication. There will be a list of options to choose from under 'Action to take when request is not authenticated'. Please make sure that this value is not set to 'Allow Anonymous requests (no action)'. Note: If you are implementing this control via code, then you can attest to the same and mark this as passed. Note: In case of Functions apps, AAD authentication is required only for 'Http Trigger' functions.", "Tags": [ "SDL", "TCP", "Automated", "AuthN", "AppService" ], "ControlEvaluationDetails": { "RequiredProperties": [ "AuthAtRootPageEnabled" ] }, "Enabled": false, "CustomTags": [ "Windows", "Linux" ] }, { "ControlID": "Azure_AppService_DP_Avoid_Plaintext_Secrets_Trial", "Description": "AppService must not have secrets/credentials present in plain text", "Id": "AppService470", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "AvoidPlaintextSecrets", "DisplayName": "AppService must not have secrets/credentials present in plain text", "Category": "Credentials Access", "ControlRequirements": "Eliminating plain text credentials", "Rationale": "Keeping secrets/credentials such as DB connection strings, passwords, keys, etc. in plain text can lead to exposure at various avenues during an application's lifecycle. Storing them in a key vault ensures that they are protected at rest.", "Recommendation": "Find detected secrets/credentials using the API information available in Source, rotate those credentials and remove them. Use KeyVault to store secrets/credentials.", "Tags": [ "SDL", "TCP", "Automated", "DP", "Baseline", "Daily", "Trial" ], "Enabled": true }, { "ControlID": "Azure_AppService_DP_Use_Secure_FTP_Deployment", "Description": "App Services should use secure FTP deployments", "Id": "AppService480", "ControlSeverity": "Medium", "Automated": "Yes", "ControlScanSource": "MDCandReader", "MethodName": "CheckAppServiceFtpDeployment", "DisplayName": "App Services should use secure FTP deployments", "Category": "Encrypt data in transit", "ControlRequirements": "Data must be encrypted in transit and at rest", "Rationale": "FTPS is used to enhance security for your Azure Web Application as it adds an extra layer of security to the FTP protocol,Enforcing FTPS-only Access for your Azure App Services apps can guarantee that the encrypted traffic between the web apps and servers and the FTP clients cannot be decrypted by malicious actors", "Recommendation": "To make production slot compliant,Go to Azure Portal --> your App Service --> Settings --> Configuration --> General Settings --> FTP state -->(Choose FTPS Only/Disabled based on requirement)--> Save.To make non-production slot compliant,Go to Azure Portal --> your App Service --> Deployment --> Deployment slots --> Select slot --> Settings --> Configuration --> General Settings --> FTP state -->(Choose FTPS Only/Disabled based on requirement)--> Save", "Tags": [ "Baseline", "Weekly" ], "AssessmentProperties": { "AssessmentNames": [ "972a6579-f38f-c0b9-1b4b-a5bbeba3ab5b", "19beaa2a-a126-b4dd-6d35-617f6cc83fca" ], "AssessmentStatusMappings": [ { "AssessmentStatusCode": "NotApplicable", "EffectiveVerificationResult": "Failed", "AssessmentStatusCausePatterns": "(.)OffByPolicy|Exempt(.)", "AppendMessageToStatusReason": "Disabling or exempting the policy from getting evaluated is not recommended. The Control will be marked as Failed." } ] }, "Enabled": true, "ControlEvaluationDetails": { "RequiredProperties": [ "SiteConfig", "SlotSiteConfig" ] }, "CustomTags": [ "Windows", "Linux" ] } ] } |