From f84c0ad25758603b0a2850d469e78865cc40cc92 Mon Sep 17 00:00:00 2001 From: Jack Tracey <41163455+jtracey93@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:37:03 +0000 Subject: [PATCH] feat: Add WAF Security PS Rule Config (#3745) ## Description Add WAF Security PS Rule Config as agreed, defined below: 1. New PSRule custom baseline with explicit rules added based on WAF security work, prioritizing top 20 resources 2. Run of PSRule with `Azure.Pillar.Security` in "audit only" mode (`continue_on_error = true`) ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.container-registry.registry](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml/badge.svg?branch=feat%2Fadd-waf-security)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml) - Note failure is not due to changes and is in different job | | [![avm.res.network.firewall-policy](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.firewall-policy.yml/badge.svg)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.firewall-policy.yml) - failing as rule is not passing as expected | | [![avm.res.network.azure-firewall](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.azure-firewall.yml/badge.svg?branch=feat%2Fadd-waf-security)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.azure-firewall.yml) | |[![avm.res.network.application-gateway-web-application-firewall-policy](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway-web-application-firewall-policy.yml/badge.svg?branch=feat%2Fadd-waf-security)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway-web-application-firewall-policy.yml) | | [![avm.res.network.application-gateway](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway.yml/badge.svg)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway.yml) - failing as expected | | [![avm.res.storage.storage-account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml/badge.svg)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.storage.storage-account.yml) - Note failure is not due to changes and is in different job| ## Type of Change - [x] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../avm-validateModulePSRule/action.yml | 29 +++++++++++ .github/workflows/avm.template.module.yml | 48 ++++++++++++++++++- .../psrule/.ps-rule/cb-waf-security.Rule.yaml | 46 ++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 avm/utilities/pipelines/staticValidation/psrule/.ps-rule/cb-waf-security.Rule.yaml diff --git a/.github/actions/templates/avm-validateModulePSRule/action.yml b/.github/actions/templates/avm-validateModulePSRule/action.yml index 88c123fca6..ab29a6d245 100644 --- a/.github/actions/templates/avm-validateModulePSRule/action.yml +++ b/.github/actions/templates/avm-validateModulePSRule/action.yml @@ -131,6 +131,35 @@ runs: source: "${{ inputs.psrulePath}}/.ps-rule/" # Path to folder containing suppression rules to use for analysis. summary: false # Disabling as taken care in customized task + - name: Run PSRule analysis - Security Pillar Only (Custom Security Pillar) + uses: microsoft/ps-rule@v2.9.0 + if: ${{ inputs.psruleBaseline == 'CB.AVM.WAF.Security' }} + with: + modules: "PSRule.Rules.Azure" + prerelease: true + baseline: "${{ inputs.psruleBaseline }}" + inputPath: "${{ inputs.templateFilePath}}" + outputFormat: Csv + outputPath: "${{ inputs.templateFilePath}}-PSRule-output.csv" + option: "${{ github.workspace }}/${{ inputs.psrulePath}}/ps-rule.yaml" # Path to PSRule configuration options file + source: "${{ inputs.psrulePath}}/.ps-rule/" # Path to folder containing suppression rules to use for analysis. + summary: false # Disabling as taken care in customized task + + - name: Run PSRule analysis - Security Pillar Only (Azure.Pillar.Security) + uses: microsoft/ps-rule@v2.9.0 + if: ${{ inputs.psruleBaseline == 'Azure.Pillar.Security' }} + continue-on-error: true + with: + modules: "PSRule.Rules.Azure" + prerelease: true + baseline: "${{ inputs.psruleBaseline }}" + inputPath: "${{ inputs.templateFilePath}}" + outputFormat: Csv + outputPath: "${{ inputs.templateFilePath}}-PSRule-output.csv" + option: "${{ github.workspace }}/${{ inputs.psrulePath}}/ps-rule.yaml" # Path to PSRule configuration options file + source: "${{ inputs.psrulePath}}/.ps-rule/" # Path to folder containing suppression rules to use for analysis. + summary: false # Disabling as taken care in customized task + - name: "Parse CSV content" if: always() uses: azure/powershell@v2 diff --git a/.github/workflows/avm.template.module.yml b/.github/workflows/avm.template.module.yml index 4df961c68e..f7b409ce9a 100644 --- a/.github/workflows/avm.template.module.yml +++ b/.github/workflows/avm.template.module.yml @@ -94,6 +94,50 @@ jobs: psrulePath: "avm/utilities/pipelines/staticValidation/psrule" #'${{ github.workspace }}/avm' psruleBaseline: "Azure.Pillar.Reliability" + job_psrule_test_waf_security_cb: # Note: Please don't change this job name. It is used by the setEnvironment action to define which PS modules to install on runners. + name: "PSRule - WAF Security - AVM Custom Baseline [${{ matrix.testCases.name }}]" + runs-on: ubuntu-latest + if: ${{ inputs.psRuleModuleTestFilePaths != '' && (fromJson(inputs.workflowInput)).staticValidation == 'true' }} + strategy: + fail-fast: false + matrix: + testCases: ${{ fromJson(inputs.psRuleModuleTestFilePaths) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set environment + uses: ./.github/actions/templates/avm-setEnvironment + - name: "Run PSRule validation with [${{ matrix.testCases.path }}]" + uses: ./.github/actions/templates/avm-validateModulePSRule + with: + templateFilePath: "${{ inputs.modulePath }}/${{ matrix.testCases.path }}" + subscriptionId: "${{ secrets.ARM_SUBSCRIPTION_ID }}" + managementGroupId: "${{ secrets.ARM_MGMTGROUP_ID }}" + psrulePath: "avm/utilities/pipelines/staticValidation/psrule" #'${{ github.workspace }}/avm' + psruleBaseline: "CB.AVM.WAF.Security" + + job_psrule_test_waf_security: # Note: Please don't change this job name. It is used by the setEnvironment action to define which PS modules to install on runners. + name: "PSRule - WAF Security [${{ matrix.testCases.name }}]" + runs-on: ubuntu-latest + if: ${{ inputs.psRuleModuleTestFilePaths != '' && (fromJson(inputs.workflowInput)).staticValidation == 'true' }} + strategy: + fail-fast: false + matrix: + testCases: ${{ fromJson(inputs.psRuleModuleTestFilePaths) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set environment + uses: ./.github/actions/templates/avm-setEnvironment + - name: "Run PSRule validation with [${{ matrix.testCases.path }}]" + uses: ./.github/actions/templates/avm-validateModulePSRule + with: + templateFilePath: "${{ inputs.modulePath }}/${{ matrix.testCases.path }}" + subscriptionId: "${{ secrets.ARM_SUBSCRIPTION_ID }}" + managementGroupId: "${{ secrets.ARM_MGMTGROUP_ID }}" + psrulePath: "avm/utilities/pipelines/staticValidation/psrule" #'${{ github.workspace }}/avm' + psruleBaseline: "Azure.Pillar.Security" + ############################# # Deployment validation # ############################# @@ -104,10 +148,12 @@ jobs: !cancelled() && (fromJson(inputs.workflowInput)).deploymentValidation == 'true' && needs.job_module_static_validation.result != 'failure' && - needs.job_psrule_test_waf_reliability.result != 'failure' + needs.job_psrule_test_waf_reliability.result != 'failure' && + needs.job_psrule_test_waf_security_cb.result != 'failure' needs: - job_module_static_validation - job_psrule_test_waf_reliability + - job_psrule_test_waf_security_cb strategy: fail-fast: false matrix: diff --git a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/cb-waf-security.Rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/cb-waf-security.Rule.yaml new file mode 100644 index 0000000000..3620b3c9bd --- /dev/null +++ b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/cb-waf-security.Rule.yaml @@ -0,0 +1,46 @@ +--- +# Synopsis: Custom baseline for AVM WAF security pillar recommendations that are enforced in CI. +apiVersion: github.com/microsoft/PSRule/v1 +kind: Baseline +metadata: + name: CB.AVM.WAF.Security +spec: + rule: + include: + - Azure.ACR.AdminUser + - Azure.ACR.ContainerScan + - Azure.ACR.ContentTrust + - Azure.ACR.Firewall + - Azure.AKS.AzureRBAC + - Azure.AppGw.UseHTTPS + - Azure.AppGw.SSLPolicy + - Azure.AppGw.WAFEnabled + - Azure.AppGw.UseWAF + - Azure.AppService.WebSecureFtp + - Azure.AppService.MinTLS + - Azure.Cosmos.MinTLS + - Azure.Defender.Api + - Azure.Defender.AppServices + - Azure.Defender.Arm + - Azure.Defender.Containers + - Azure.Defender.CosmosDb + - Azure.Defender.Cspm + - Azure.Defender.Dns + - Azure.Defender.KeyVault + - Azure.Defender.OssRdb + - Azure.Defender.SQL + - Azure.Defender.SQLOnVM + - Azure.Defender.SecurityContact + - Azure.Defender.Servers + - Azure.Defender.Storage.DataScan + - Azure.Defender.Storage.MalwareScan + - Azure.Defender.Storage + - Azure.Firewall.Mode + - Azure.Firewall.PolicyMode + - Azure.Storage.DefenderCloud + - Azure.Storage.Defender.MalwareScan + - Azure.Storage.SecureTransfer + - Azure.Storage.BlobPublicAccess + - Azure.Storage.BlobAccessType + - Azure.Storage.Firewall + - Azure.Storage.MinTLS