Skip to content

Commit

Permalink
Fixes Azure.AppService.PHPVersion when phpVersion is null #2768 (#2770)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Mar 24, 2024
1 parent 4653664 commit 71b205d
Show file tree
Hide file tree
Showing 11 changed files with 648 additions and 99 deletions.
8 changes: 8 additions & 0 deletions data/policy-ignore.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,13 @@
],
"reason": "Duplicate",
"value": "Azure.AppService.WebSecureFtp"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/7261b898-8a84-4db8-9e04-18527132abb3",
"/providers/Microsoft.Authorization/policyDefinitions/f466b2a6-823d-470d-8ea5-b031e72d79ae"
],
"reason": "Duplicate",
"value": "Azure.AppService.PHPVersion"
}
]
4 changes: 4 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ What's changed since pre-release v1.35.0-B0030:
- Updated `Azure.AppService.NETVersion` to detect out of date .NET versions including .NET 5/6/7 by @BernieWhite.
[#2766](https://github.com/Azure/PSRule.Rules.Azure/issues/2766)
- Bumped rule set to `2024_03`.
- Updated `Azure.AppService.PHPVersion` to detect out of date PHP versions before 8.2 by @BernieWhite.
[#2768](https://github.com/Azure/PSRule.Rules.Azure/issues/2768)
- Fixed `Azure.AppService.PHPVersion` check fails when phpVersion is null.
- Bumped rule set to `2024_03`.
- General improvements:
- Quality updates to rule documentation by @BernieWhite.
[#2570](https://github.com/Azure/PSRule.Rules.Azure/issues/2570)
Expand Down
96 changes: 56 additions & 40 deletions docs/en/rules/Azure.AppService.PHPVersion.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
reviewed: 2022-05-14
reviewed: 2024-03-24
severity: Important
pillar: Security
category: Deployment
category: SE:02 Secured development lifecycle
resource: App Service
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppService.PHPVersion/
---
Expand All @@ -16,62 +16,65 @@ Configure applications to use newer PHP runtime versions.
## DESCRIPTION

Within a App Service app, the version of PHP runtime used to run application/ site code is configurable.
Older versions of PHP may not use the latest security features.

Overtime, a specific version of PHP may become outdated and no longer supported by Microsoft in Azure App Service.
This can lead to security vulnerabilities or are simply not able to use the latest security features.

PHP 8.0 and 8.1 are approaching end of support.

## RECOMMENDATION

Consider updating the site to use a newer PHP runtime version such as `7.4`.
Consider updating the site to use a newer PHP runtime version such as `8.2`.

## EXAMPLES

### Configure with Azure template

To deploy App Services that pass this rule:

- Set `properties.siteConfig.phpVersion` to a minimum of `7.0`.
- Set `properties.siteConfig.linuxFxVersion` to a minimum of `PHP|8.2`.

For example:

```json
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-03-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"kind": "web",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]",
"httpsOnly": true,
"siteConfig": {
"alwaysOn": true,
"minTlsVersion": "1.2",
"ftpsState": "FtpsOnly",
"remoteDebuggingEnabled": false,
"http20Enabled": true,
"netFrameworkVersion": "OFF",
"phpVersion": "7.4"
}
},
"tags": "[parameters('tags')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]"
]
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"kind": "web",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]",
"httpsOnly": true,
"clientAffinityEnabled": false,
"siteConfig": {
"alwaysOn": true,
"minTlsVersion": "1.2",
"ftpsState": "Disabled",
"http20Enabled": true,
"healthCheckPath": "/healthz",
"linuxFxVersion": "PHP|8.2"
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]"
]
}
```

### Configure with Bicep

To deploy App Services that pass this rule:

- Set `properties.siteConfig.phpVersion` to a minimum of `7.0`.
- Set `properties.siteConfig.linuxFxVersion` to a minimum of `PHP|8.2`.

For example:

```bicep
resource webAppPHP 'Microsoft.Web/sites@2021-03-01' = {
resource php 'Microsoft.Web/sites@2023-01-01' = {
name: name
location: location
identity: {
Expand All @@ -81,22 +84,35 @@ resource webAppPHP 'Microsoft.Web/sites@2021-03-01' = {
properties: {
serverFarmId: plan.id
httpsOnly: true
clientAffinityEnabled: false
siteConfig: {
alwaysOn: true
minTlsVersion: '1.2'
ftpsState: 'FtpsOnly'
remoteDebuggingEnabled: false
ftpsState: 'Disabled'
http20Enabled: true
netFrameworkVersion: 'OFF'
phpVersion: '7.4'
healthCheckPath: '/healthz'
linuxFxVersion: 'PHP|8.2'
}
}
tags: tags
}
```

### Configure with Azure Policy

To address this issue at runtime use the following policies:

- [App Service apps that use PHP should use a specified 'PHP version'](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/Webapp_Audit_PHP_Latest.json)
`/providers/Microsoft.Authorization/policyDefinitions/7261b898-8a84-4db8-9e04-18527132abb3`
- [App Service app slots that use PHP should use a specified 'PHP version'](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/App%20Service/Webapp_Slot_Audit_PHP_Latest.json)
`/providers/Microsoft.Authorization/policyDefinitions/f466b2a6-823d-470d-8ea5-b031e72d79ae`

## NOTES

From November 2022 - PHP is only supported on Linux-based plans.

## LINKS

- [Security design principles](https://learn.microsoft.com/azure/architecture/framework/security/security-principles#protect-against-code-level-vulnerabilities)
- [Set PHP Version](https://docs.microsoft.com/azure/app-service/configure-language-php#set-php-version)
- [Azure deployment reference](https://docs.microsoft.com/azure/templates/microsoft.web/sites#siteconfig)
- [SE:02 Secured development lifecycle](https://learn.microsoft.com/azure/well-architected/security/secure-development-lifecycle)
- [Set PHP Version](https://learn.microsoft.com/azure/app-service/configure-language-php?pivots=platform-linux#set-php-version)
- [PHP on App Service](https://github.com/Azure/app-service-linux-docs/blob/master/Runtime_Support/php_support.md)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.web/sites)
24 changes: 24 additions & 0 deletions docs/examples-appservice.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ resource web 'Microsoft.Web/sites@2023-01-01' = {
properties: {
serverFarmId: plan.id
httpsOnly: true
clientAffinityEnabled: false
siteConfig: {
alwaysOn: true
minTlsVersion: '1.2'
Expand All @@ -54,6 +55,29 @@ 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' = {
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'
http20Enabled: true
healthCheckPath: '/healthz'
linuxFxVersion: 'PHP|8.2'
}
}
}

// Disable basic publishing credentials for FTP.
resource ftp 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01' = {
parent: web
Expand Down
29 changes: 28 additions & 1 deletion docs/examples-appservice.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "210994321631769997"
"templateHash": "10435733640424545318"
}
},
"parameters": {
Expand Down Expand Up @@ -55,6 +55,7 @@
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]",
"httpsOnly": true,
"clientAffinityEnabled": false,
"siteConfig": {
"alwaysOn": true,
"minTlsVersion": "1.2",
Expand All @@ -75,6 +76,32 @@
"[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]"
]
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"kind": "web",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]",
"httpsOnly": true,
"clientAffinityEnabled": false,
"siteConfig": {
"alwaysOn": true,
"minTlsVersion": "1.2",
"ftpsState": "Disabled",
"http20Enabled": true,
"healthCheckPath": "/healthz",
"linuxFxVersion": "PHP|8.2"
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('planName'))]"
]
},
{
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2023-01-01",
Expand Down
35 changes: 24 additions & 11 deletions src/PSRule.Rules.Azure/rules/Azure.AppService.Rule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,33 @@ Rule 'Azure.AppService.NETVersion' -Ref 'AZR-000075' -Type 'Microsoft.Web/sites'
}

# Synopsis: Configure applications to use newer PHP runtime versions.
Rule 'Azure.AppService.PHPVersion' -Ref 'AZR-000076' -Type 'Microsoft.Web/sites', 'Microsoft.Web/sites/slots' -Tag @{ release = 'GA'; ruleSet = '2020_12'; 'Azure.WAF/pillar' = 'Security'; } {
$siteConfigs = @(GetWebSiteConfig | Where-Object {
![String]::IsNullOrEmpty($_.Properties.phpVersion)
})
Rule 'Azure.AppService.PHPVersion' -Ref 'AZR-000076' -Type 'Microsoft.Web/sites', 'Microsoft.Web/sites/slots' -Tag @{ release = 'GA'; ruleSet = '2024_03'; 'Azure.WAF/pillar' = 'Security'; } {
$siteConfigs = @(GetWebSiteConfig)
if ($siteConfigs.Length -eq 0) {
return AnyOf {
$Assert.HasDefaultValue($TargetObject, 'Properties.siteConfig.phpVersion', 'OFF')
$Assert.Version($TargetObject, 'Properties.siteConfig.phpVersion', '>=7.0')
if ($Assert.HasFieldValue($TargetObject, 'properties.siteConfig.linuxFxVersion').Result -and $TargetObject.properties.siteConfig.linuxFxVersion -like 'PHP|*') {
$linuxVersion = $TargetObject.properties.siteConfig.linuxFxVersion.Split('|')[1];
return $Assert.Version($linuxVersion, '.', '>=8.2').PathPrefix('properties.siteConfig.linuxFxVersion');
}
elseif (!$Assert.HasDefaultValue($TargetObject, 'properties.siteConfig.phpVersion', 'OFF').Result -and
![String]::IsNullOrEmpty($TargetObject.properties.siteConfig.phpVersion)) {
return $Assert.Version($TargetObject, 'properties.siteConfig.phpVersion', '>=8.2');
}
else {
return $Assert.Pass();
}
}
foreach ($siteConfig in $siteConfigs) {
AnyOf {
$Assert.HasFieldValue($siteConfig, 'Properties.phpVersion', 'OFF')
$Assert.Version($siteConfig, 'Properties.phpVersion', '>=7.0')
$path = $siteConfig._PSRule.path;
if ($Assert.HasFieldValue($siteConfig, 'properties.linuxFxVersion').Result -and $siteConfig.properties.linuxFxVersion -like 'PHP|*') {
$linuxVersion = $siteConfig.properties.linuxFxVersion.Split('|')[1];
$Assert.Version($linuxVersion, '.', '>=8.2').PathPrefix("$path.properties.linuxFxVersion");
}
elseif (!$Assert.HasDefaultValue($siteConfig, 'properties.phpVersion', 'OFF').Result -and
![String]::IsNullOrEmpty($siteConfig.properties.phpVersion)) {
$Assert.Version($siteConfig, 'properties.phpVersion', '>=8.2').PathPrefix($path);
}
else {
$Assert.Pass();
}
}
}
Expand All @@ -96,7 +109,7 @@ Rule 'Azure.AppService.AlwaysOn' -Ref 'AZR-000077' -Type 'Microsoft.Web/sites',
return $Assert.HasFieldValue($TargetObject, 'Properties.siteConfig.alwaysOn', $True);
}
foreach ($siteConfig in $siteConfigs) {
$Assert.HasFieldValue($siteConfig, 'Properties.alwaysOn', $True);
$Assert.HasFieldValue($siteConfig, 'properties.alwaysOn', $True);
}
}

Expand Down
14 changes: 8 additions & 6 deletions src/PSRule.Rules.Azure/rules/Azure.AppService.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,15 @@ spec:
allOf:
- type: '.'
in:
- 'Microsoft.Web/sites'
- 'Microsoft.Web/sites/slots'
- Microsoft.Web/sites
- Microsoft.Web/sites/slots
- anyOf:
- field: kind
exists: false
- field: kind
equals: 'app'
in:
- app
- app,linux

---
# Synopsis: App Service sites that are API apps.
Expand All @@ -145,10 +147,10 @@ spec:
allOf:
- type: '.'
in:
- 'Microsoft.Web/sites'
- 'Microsoft.Web/sites/slots'
- Microsoft.Web/sites
- Microsoft.Web/sites/slots
- field: kind
equals: 'api'
equals: api

---
# Synopsis: App Service sites that are Function apps.
Expand Down
Loading

0 comments on commit 71b205d

Please sign in to comment.