Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated minimum TLS for App Service #3269 #3275

Merged
merged 2 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions data/policy-ignore.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,5 +304,15 @@
],
"reason": "Duplicate",
"value": "Azure.ACR.AnonymousAccess"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/f0e6e85b-9b9f-4a4b-b67b-f730d42f1b0b",
"/providers/Microsoft.Authorization/policyDefinitions/4ee5b817-627a-435a-8932-116193268172",
"/providers/Microsoft.Authorization/policyDefinitions/ae44c1d1-0df2-4ca9-98fa-a3d3ae5b409d",
"/providers/Microsoft.Authorization/policyDefinitions/014664e7-e348-41a3-aeb9-566e4ff6a9df"
],
"reason": "Duplicate",
"value": "Azure.AppService.MinTLS"
}
]
6 changes: 6 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ What's changed since v1.41.4:
- Image Builder:
- Check that image builder build and validation scripts are pinned by @BernieWhite.
[#2903](https://github.com/Azure/PSRule.Rules.Azure/issues/2903)
- Updated rules:
- App Service:
- Updated `Azure.AppService.MinTLS` to include TLS 1.3 as a valid minimum version by @BernieWhite.
[#3269](https://github.com/Azure/PSRule.Rules.Azure/issues/3269)
- General improvements:
- Added a new quickstart guide for using Azure Pipelines with PSRule by @that-ar-guy.
[#3220](https://github.com/Azure/PSRule.Rules.Azure/pull/3220)
- Added additional exclusions to policies for `Azure.AppService.MinTLS` by @BernieWhite.
[#1731](https://github.com/Azure/PSRule.Rules.Azure/issues/1731)
- Engineering:
- Updates to WAF documentation by @BernieWhite.
[#2570](https://github.com/Azure/PSRule.Rules.Azure/issues/2570)
Expand Down
2 changes: 1 addition & 1 deletion docs/en/rules/Azure.ACR.AnonymousAccess.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ resource: Container Registry
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ACR.AnonymousAccess/
---

# Container registry anonymous pull access is enabled
# Container Registry anonymous pull access is enabled

## SYNOPSIS

Expand Down
93 changes: 54 additions & 39 deletions docs/en/rules/Azure.AppService.MinTLS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
reviewed: 2025-03-07
severity: Critical
pillar: Security
category: SE:07 Encryption
Expand All @@ -7,7 +8,7 @@ online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppSer
ms-content-id: e19fbe7e-da05-47d4-8de1-2fdf52ada662
---

# Use secure protocols for App Service
# App Service site allows insecure TLS versions

## SYNOPSIS

Expand All @@ -28,11 +29,52 @@ Also consider using Azure Policy to audit or enforce this configuration.

## EXAMPLES

### Configure with Bicep

To deploy App Services that pass this rule:

- Set the `properties.siteConfig.minTlsVersion` property to `1.2` or `1.3`.

For example:

```bicep
resource web 'Microsoft.Web/sites@2024-04-01' = {
name: name
location: location
identity: {
type: 'SystemAssigned'
}
kind: 'web'
properties: {
serverFarmId: plan.id
httpsOnly: true
clientAffinityEnabled: false
siteConfig: {
alwaysOn: true
minTlsVersion: '1.2'
ftpsState: 'Disabled'
remoteDebuggingEnabled: false
http20Enabled: true
netFrameworkVersion: 'v8.0'
healthCheckPath: '/healthz'
metadata: [
{
name: 'CURRENT_STACK'
value: 'dotnet'
}
]
}
}
}
```

<!-- external:avm avm/res/web/site siteConfig.minTlsVersion -->

### Configure with Azure template

To deploy App Services that pass this rule:

- Set the `properties.siteConfig.minTlsVersion` property to `1.2`.
- Set the `properties.siteConfig.minTlsVersion` property to `1.2` or `1.3`.

For example:

Expand Down Expand Up @@ -71,45 +113,18 @@ For example:
}
```

### Configure with Bicep

To deploy App Services that pass this rule:

- Set the `properties.siteConfig.minTlsVersion` property to `1.2`.
### Configure with Azure Policy

For example:

```bicep
resource web 'Microsoft.Web/sites@2023-01-01' = {
name: name
location: location
identity: {
type: 'SystemAssigned'
}
kind: 'web'
properties: {
serverFarmId: plan.id
httpsOnly: true
siteConfig: {
alwaysOn: true
minTlsVersion: '1.2'
ftpsState: 'Disabled'
remoteDebuggingEnabled: false
http20Enabled: true
netFrameworkVersion: 'v8.0'
healthCheckPath: '/healthz'
metadata: [
{
name: 'CURRENT_STACK'
value: 'dotnet'
}
]
}
}
}
```
To address this issue at runtime use the following policies:

<!-- external:avm avm/res/web/site siteConfig.minTlsVersion -->
- [App Service apps should use the latest TLS version](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/RequireLatestTls_WebApp_Audit.json)
`/providers/Microsoft.Authorization/policyDefinitions/f0e6e85b-9b9f-4a4b-b67b-f730d42f1b0b`.
- [App Service app slots should use the latest TLS version](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/RequireLatestTls_WebApp_Slot_Audit.json)
`/providers/Microsoft.Authorization/policyDefinitions/4ee5b817-627a-435a-8932-116193268172`.
- [Configure App Service apps to use the latest TLS version](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/RequireLatestTls_WebApp_DINE.json)
`/providers/Microsoft.Authorization/policyDefinitions/ae44c1d1-0df2-4ca9-98fa-a3d3ae5b409d`.
- [Configure App Service app slots to use the latest TLS version](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/RequireLatestTls_WebApp_Slot_DINE.json)
`/providers/Microsoft.Authorization/policyDefinitions/014664e7-e348-41a3-aeb9-566e4ff6a9df`.

## LINKS

Expand Down
2 changes: 1 addition & 1 deletion docs/en/rules/Azure.ImageBuilder.CustomizeHash.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ reviewed: 2025-03-06
severity: Important
pillar: Security
category: SE:02 Secured development lifecycle
resource: Image Builder
resource: VM Image Builder
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ImageBuilder.CustomizeHash/
---

Expand Down
2 changes: 1 addition & 1 deletion docs/en/rules/Azure.ImageBuilder.ValidateHash.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ reviewed: 2025-03-06
severity: Important
pillar: Security
category: SE:02 Secured development lifecycle
resource: Image Builder
resource: VM Image Builder
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ImageBuilder.ValidateHash/
---

Expand Down
12 changes: 6 additions & 6 deletions docs/examples/resources/appservice.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ param planName string
param location string = resourceGroup().location

// An example App Services Plan.
resource plan 'Microsoft.Web/serverfarms@2023-01-01' = {
resource plan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: planName
location: location
sku: {
Expand All @@ -26,7 +26,7 @@ resource plan 'Microsoft.Web/serverfarms@2023-01-01' = {
}

// An example .NET Framework Web App running on a Windows App Services Plan.
resource web 'Microsoft.Web/sites@2023-01-01' = {
resource web 'Microsoft.Web/sites@2024-04-01' = {
name: name
location: location
identity: {
Expand Down Expand Up @@ -56,7 +56,7 @@ resource web 'Microsoft.Web/sites@2023-01-01' = {
}

// An example PHP Web App running on a Linux App Services Plan.
resource php 'Microsoft.Web/sites@2023-01-01' = {
resource php 'Microsoft.Web/sites@2024-04-01' = {
name: name
location: location
identity: {
Expand All @@ -79,7 +79,7 @@ resource php 'Microsoft.Web/sites@2023-01-01' = {
}

// Disable basic publishing credentials for FTP.
resource ftp 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01' = {
resource ftp 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2024-04-01' = {
parent: web
name: 'ftp'
properties: {
Expand All @@ -88,7 +88,7 @@ resource ftp 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01'
}

// Disable basic publishing credentials over SCM.
resource scm 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01' = {
resource scm 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2024-04-01' = {
parent: web
name: 'scm'
properties: {
Expand All @@ -97,7 +97,7 @@ resource scm 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01'
}

// An example PHP Web App
resource webAppPHP 'Microsoft.Web/sites@2023-01-01' = {
resource webAppPHP 'Microsoft.Web/sites@2024-04-01' = {
name: name
location: location
identity: {
Expand Down
16 changes: 8 additions & 8 deletions docs/examples/resources/appservice.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "10435733640424545318"
"version": "0.33.93.31351",
"templateHash": "12567330257424459921"
}
},
"parameters": {
Expand All @@ -32,7 +32,7 @@
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[parameters('planName')]",
"location": "[parameters('location')]",
"sku": {
Expand All @@ -45,7 +45,7 @@
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
Expand Down Expand Up @@ -78,7 +78,7 @@
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
Expand All @@ -104,7 +104,7 @@
},
{
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[format('{0}/{1}', parameters('name'), 'ftp')]",
"properties": {
"allow": false
Expand All @@ -115,7 +115,7 @@
},
{
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[format('{0}/{1}', parameters('name'), 'scm')]",
"properties": {
"allow": false
Expand All @@ -126,7 +126,7 @@
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"apiVersion": "2024-04-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
Expand Down
12 changes: 5 additions & 7 deletions src/PSRule.Rules.Azure/rules/Azure.AppService.Rule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@ Rule 'Azure.AppService.PlanInstanceCount' -Ref 'AZR-000071' -Type 'Microsoft.Web
$Assert.GreaterOrEqual($TargetObject, 'sku.capacity', 2);
}

# Synopsis: App Service should reject TLS versions older than 1.2.
# Synopsis: App Service should not accept weak or deprecated transport protocols for client-server communication.
Rule 'Azure.AppService.MinTLS' -Ref 'AZR-000073' -Type 'Microsoft.Web/sites', 'Microsoft.Web/sites/slots' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = 'DP-3' } {
$siteConfigs = @(GetWebSiteConfig);
if ($siteConfigs.Length -eq 0) {
return $Assert.
HasFieldValue($TargetObject, 'properties.siteConfig.minTlsVersion', '1.2').
ReasonFrom('properties.siteConfig.minTlsVersion', $LocalizedData.MinTLSVersion, $TargetObject.properties.siteConfig.minTlsVersion);
return $Assert.Version($TargetObject, 'properties.siteConfig.minTlsVersion', '>=1.2').
ReasonFrom('properties.siteConfig.minTlsVersion', $LocalizedData.MinTLSVersion, $TargetObject.properties.siteConfig.minTlsVersion);
}
foreach ($siteConfig in $siteConfigs) {
$path = $siteConfig._PSRule.path;
$Assert.
HasFieldValue($siteConfig, 'properties.minTlsVersion', '1.2').
ReasonFrom('properties.minTlsVersion', $LocalizedData.MinTLSVersion, $siteConfig.properties.minTlsVersion).PathPrefix($path);
$Assert.Version($siteConfig, 'properties.minTlsVersion', '>=1.2').
ReasonFrom('properties.minTlsVersion', $LocalizedData.MinTLSVersion, $siteConfig.properties.minTlsVersion).PathPrefix($path);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void GetPolicyDefinitionWithIgnore()

var definitions = context.GetDefinitions();
Assert.NotNull(definitions);
Assert.Equal(111, definitions.Length);
Assert.Equal(110, definitions.Length);

// Check category and version
var actual = definitions.FirstOrDefault(definition => definition.DefinitionId == "/providers/Microsoft.Authorization/policyDefinitions/34c877ad-507e-4c82-993e-3452a6e0ad3c");
Expand Down
2 changes: 1 addition & 1 deletion tests/PSRule.Rules.Azure.Tests/Resources.AppService.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@
],
"scmIpSecurityRestrictionsUseMain": false,
"http20Enabled": true,
"minTlsVersion": "1.2",
"minTlsVersion": "1.3",
"ftpsState": "FtpsOnly",
"reservedInstanceCount": 0,
"preWarmedInstanceCount": null,
Expand Down
Loading