Azure Application Gateway: Web Application Firewall (WAF) Configuratie

💼 Management Samenvatting

Azure Application Gateway met Web Application Firewall (WAF) vormt een kritieke verdedigingslaag voor webapplicaties van Nederlandse overheden en vitale organisaties. Waar traditionele netwerkfirewalls vooral verkeer op poort- en IP-niveau filteren, analyseert WAF HTTP(S)-verkeer diepgaand op patronen die wijzen op SQL-injectie, Cross-Site Scripting (XSS), Remote Code Execution (RCE) en andere OWASP Top 10-risico's. Door WAF dicht bij de applicatie te positioneren, in combinatie met loadbalancing en TLS-terminatie, ontstaat een centraal aangrijpingspunt waar beveiligingsbeleid consistent kan worden afgedwongen en gemonitord over meerdere applicaties en omgevingen heen.

Aanbeveling
SCHAKEL APPLICATION GATEWAY WAF IN VOOR ALLE INTERNETGERICHTE WEBAPPLICATIES
Risico zonder
Critical
Risk Score
9/10
Implementatie
32u (tech: 24u)
Van toepassing op:
Azure Application Gateway
Azure Web Application Firewall
Internetgerichte webapplicaties

Zonder een goed geconfigureerde WAF op Application Gateway is elke internetgerichte applicatie rechtstreeks blootgesteld aan geautomatiseerde scans, botnets en gerichte aanvallen. In de praktijk blijkt dat veel overheidsorganisaties wel kwetsbaarheden oplossen in applicatiecode, maar geen structurele bescherming hebben tegen zero-day exploits of misconfiguraties in frameworks en middleware. Aanvallers hoeven dan slechts één fout in een webframework of plug-in te vinden om toegang te krijgen tot persoonsgegevens, basisregistraties of bestuurlijke documenten. Bovendien ontbreekt zonder WAF vaak een centraal zicht op aanvallen: logging is versnipperd over applicaties, ontwikkelteams en omgevingen. Daarmee is het vrijwel onmogelijk om bij incidenten snel te reconstrueren hoe lang een aanval al bezig was, welke payloads zijn gebruikt en welke endpoints het hardst zijn geraakt. Voor instellingen die moeten aantonen dat zij onder BIO, NIS2 en AVG "passende technische maatregelen" hebben getroffen, is dit een onacceptabele situatie: auditors verwachten een aantoonbare defense-in-depth-opzet waarin WAF een expliciete control vormt voor webverkeer.

PowerShell Modules Vereist
Primary API: Azure API
Connection: Connect-AzAccount
Required Modules: Az.Network, Az.Resources, Az.Accounts

Implementatie

Dit artikel beschrijft hoe organisaties binnen de Nederlandse Baseline voor Veilige Cloud Application Gateway met WAF_v2 inrichten als robuuste, centraal beheerde beveiligingslaag voor webapplicaties. De focus ligt op drie pijlers. Ten eerste ontwerp en basisconfiguratie: het kiezen van de juiste SKU, het inrichten van dedicated subnets, listeners en back-end pools, en het koppelen van één of meerdere WAF-beleidsobjecten aan specifieke sites en URL-paden. Ten tweede de concrete WAF-configuratie: activeren van OWASP Core Rule Set (CRS), kiezen tussen Detectie- en Preventiemodus, configureren van uitsluitingen en aangepaste regels, en zorgen voor volledige integratie met Log Analytics en eventueel Microsoft Sentinel. Ten derde operationalisatie en governance: hoe monitoring, incidentrespons, change management en periodieke tuning worden georganiseerd zodat WAF geen eenmalig project blijft, maar een volwassen capability wordt. Het bijbehorende PowerShell-script inventariseert Application Gateways in een abonnement, controleert of WAF is ingeschakeld, in welke modus deze draait, of een modern regelschema wordt gebruikt en of logging is geconfigureerd naar een centrale workspace. Daarmee krijgen securityteams direct inzicht in ontbrekende of verouderde configuraties en kunnen zij gericht verbeteracties initiëren.

Architectuur en randvoorwaarden voor Application Gateway WAF

Een effectieve inzet van Application Gateway met WAF begint bij een doordacht architectuurontwerp. In plaats van WAF achteraf "voor" bestaande applicaties te plaatsen, is het verstandiger om vanuit een referentiearchitectuur te werken waarin alle internetgerichte webapplicaties standaard via een centraal of gedeeld Application Gateway-platform verlopen. In zo'n ontwerp worden per omgeving (bijvoorbeeld ontwikkel, test, acceptatie, productie) één of meer gateways geplaatst in dedicated subnets binnen een hub- of spoke-architectuur. De gateways verzorgen niet alleen Layer 7-loadbalancing, maar fungeren ook als centrale terminatiepunten voor TLS, zodat certificaatbeheer en beveiligingsbeleid niet versnipperd raken. Belangrijk is dat het ontwerp rekening houdt met beschikbaarheidseisen: productie-gateways worden standaard zone-redundant en autoscaling wordt ingeschakeld, zodat volumetrische aanvallen of piekbelasting niet direct leiden tot uitval van diensten die voor burgers of ketenpartners essentieel zijn.

Randvoorwaardelijk is een helder beeld van de applicatielandschap en dataclassificatie. Voor elke webapplicatie moet bekend zijn of deze persoonsgegevens, vertrouwelijke beleidsinformatie of slechts publieke informatie verwerkt. Dit bepaalt de strengheid van het WAF-beleid, de wijze van logging en de eisen aan failover-scenario's. Applicaties met hoge dataclassificatie moeten bijvoorbeeld altijd achter een WAF in Preventiemodus draaien, met een moderne OWASP CRS-versie en aanvullende custom rules voor gevoelige functionaliteit zoals inlogschermen, uploadportalen en beheerinterfaces. Ook wordt vastgelegd welke DNS-namen en certificaten aan de gateway worden gekoppeld en hoe de relatie is met identity providers zoals Microsoft Entra ID (voorvoorbeeld voor pre-authenticated verkeer via App Service Authentication of reverse proxy-scenario's). Zonder deze inventarisatie bestaat het risico dat slechts een deel van de kritieke endpoints wordt beschermd en dat subdomeinen of beheerportalen buiten beeld blijven.

Op infrastructuurniveau vereist Application Gateway een zorgvuldig ingericht virtueel netwerk. Gateways worden geplaatst in een dedicated subnet dat alleen het gatewayverkeer bevat; back-end services zoals App Service Environments, virtuele machines of Kubernetes-clusters bevinden zich in gescheiden subnets die via netwerkbeveiligingsgroepen (NSG's) uitsluitend verkeer vanaf de gateway toestaan. Voor hybride scenario's, waarin back-end systemen on-premises of in andere clouds draaien, wordt gebruikgemaakt van VPN- of ExpressRoute-verbindingen die via firewall- of security-appliances lopen. Dit voorkomt dat WAF wordt omzeild via directe verbindingen. Tegelijkertijd worden network security-groepen zo geconfigureerd dat verkeer van internet alleen via publieke IP-adressen van de gateway kan binnenkomen. Hiermee wordt een Zero Trust-achtige opzet gerealiseerd: er bestaat geen directe inbound connectiviteit naar de applicatie zonder dat verkeer eerst door WAF is gegaan.

Een volwassen referentiearchitectuur definieert ook hoe multi-tenancy en scheiding van verantwoordelijkheden worden geborgd. Sommige organisaties kiezen voor één centrale gateway per regio, waarop meerdere WAF-beleidsobjecten zijn gekoppeld aan verschillende listeners en URL-paden. Andere organisaties geven de voorkeur aan per-dienst of per-domein gateways, zodat eigenaarschap en kostenverantwoording eenvoudig te traceren zijn. In beide gevallen moet Role-Based Access Control (RBAC) in Azure duidelijk vastleggen welke teams wijzigingen mogen doen aan de gateway zelf, wie WAF-beleid mag aanpassen en welke rollen alleen leesrechten krijgen voor monitoring en troubleshooting. Just-in-Time-toegang via Privileged Identity Management is essentieel om beheeracties te beperken in tijd en scope en om achteraf te kunnen aantonen wie welke wijziging heeft doorgevoerd.

Tot slot vraagt de Nederlandse Baseline voor Veilige Cloud expliciet aandacht voor integratie met monitoring, logging en SIEM. Bij het ontwerp van Application Gateway moet daarom direct worden vastgelegd naar welke Log Analytics-workspace de WAF- en access-logboeken worden weggeschreven, welke bewaartermijnen gelden en hoe deze gegevens worden gekoppeld aan een Security Operations Center (SOC) en incident-responsteams. Het is onvoldoende om alleen standaard logging aan te zetten; er moeten ook query's, alerts en dashboards worden gedefinieerd die inzicht geven in aanvalspatronen, false positives en trends in geblokkeerde of toegestane verzoeken. Deze architectuurkeuzes bepalen in hoge mate of WAF later daadwerkelijk als strategische control kan worden ingezet of slechts als technische optie "die ergens aan staat" zonder dat iemand echt begrijpt wat er gebeurt.

Ontwerp en configuratie van WAF-beleid op Application Gateway

Wanneer de basisarchitectuur staat, verschuift de aandacht naar het concrete WAF-beleid op Application Gateway. De kern hiervan is het kiezen van de juiste Web Application Firewall Configuration per listener of site. In moderne omgevingen wordt gebruikgemaakt van WAF_v2 met een afzonderlijk WAF Policy-object dat los van de gateway wordt beheerd en door meerdere listeners kan worden hergebruikt. Dit beleid definieert onder meer of de firewall in Detectie- of Preventiemodus draait, welke OWASP Core Rule Set (CRS) versie wordt gebruikt en welke aangepaste regels worden toegepast voor specifieke applicaties. Voor Nederlandse overheidsorganisaties geldt dat internetgerichte productieomgevingen standaard in Preventiemodus draaien met een up-to-date CRS-versie; Detectiemodus wordt alleen nog tijdelijk gebruikt voor tuning, bijvoorbeeld bij grote applicatiewijzigingen of migraties.

De keuze voor een CRS-versie is niet louter technisch, maar ook een compliancevraagstuk. Door een verouderde regelset te gebruiken, loopt de organisatie aantoonbaar achter op bekende aanvalspatronen en vergroot zij het risico dat auditors constateren dat "passende maatregelen" ontbreken. Het WAF-beleid moet daarom een proces bevatten voor het periodiek evalueren en upgraden van de CRS-versie, inclusief regressietesten in een niet-productieomgeving. Tijdens zo'n upgrade worden eerst alle regels in Detectiemodus gezet zodat logs inzicht geven in mogelijke false positives. Vervolgens worden uitzonderingen geconfigureerd voor legitieme patronen die door de nieuwe regels ten onrechte worden gezien als verdacht. Pas als de loganalyse aantoont dat het verkeer correct wordt geclassificeerd, wordt Preventiemodus weer geactiveerd op productie. Deze werkwijze voorkomt dat nieuwe regels onverwacht bedrijfsprocessen blokkeren en borgt tegelijkertijd dat de organisatie niet jarenlang op een verouderde regelset blijft hangen.

Een tweede belangrijk aspect van WAF-beleid is het zorgvuldig definiëren van uitsluitingen en custom rules. Uitsluitingen (exclusions) worden gebruikt om bepaalde headers, queryparameters of bodyvelden uit te sluiten van inspectie, bijvoorbeeld bij integraties met derde partijen die ongewone encodering of grote binaire payloads gebruiken. De Nederlandse Baseline voor Veilige Cloud schrijft hierbij het principe "zo specifiek mogelijk" voor: een uitzondering wordt altijd beperkt tot een concrete combinatie van hostnaam, pad, parameter en eventueel bron-IP of -ASN. Brede uitzonderingen zoals "negeer alle regels voor deze applicatie" zijn niet acceptabel omdat zij feitelijk de beveiligingslaag uitschakelen. Custom rules worden juist ingezet om generiek beleid verder aan te scherpen, bijvoorbeeld door brute-force bescherming op inlogroutes, geo-blokkades voor landen waaruit geen legitiem verkeer wordt verwacht, of extra validatie op upload- of beheerfuncties. Alle uitzonderingen en custom rules worden vastgelegd in een WAF-changelog met datum, reden, risico-inschatting en accordering door de security officer of CISO.

Naast verzoekinspectie moeten ook algemene instellingen zorgvuldig worden gekozen. Dit omvat limieten voor maximale requestgrootte, timeouts, toegestane HTTP-methoden en beleid rond redirects. Te lage limieten leiden tot onnodige verstoringen bij legitieme uploads of API-calls, terwijl te ruime limieten misbruik van resource-intensieve aanvallen mogelijk maken. De organisatie stelt daarom per applicatieprofiel (bijvoorbeeld burgerportaal, interne beheerapplicatie, API-gateway) standaardwaarden vast die zowel beveiligings- als gebruikseisen reflecteren. Deze waarden worden vertaald naar IaC-templates, zodat nieuwe gateways automatisch met het juiste basisbeleid worden uitgerold en afwijkingen expliciet moeten worden gemotiveerd in change-requests.

Gebruik PowerShell-script waf-configuration.ps1 (functie Invoke-Monitoring) – Voert een monitoringcontrole uit op Application Gateways om te bepalen of WAF is ingeschakeld, in welke modus deze draait en welke regels en logging zijn geconfigureerd..

Beheer, monitoring en tuning van Application Gateway WAF

Gebruik PowerShell-script waf-configuration.ps1 (functie Invoke-Assessment) – Genereert een gedetailleerd overzicht van WAF-configuratie per Application Gateway, inclusief status, modus, regels en koppeling met logvoorzieningen..

Zodra Application Gateway WAF in productie staat, verschuift de aandacht van ontwerp naar dagelijks beheer en continue verbetering. Monitoring begint met het borgen dat alle relevante gateways daadwerkelijk een WAF-configuratie hebben. Het bijbehorende PowerShell-script inventariseert periodiek alle Application Gateways in de abonnementen die onder het beheer van de organisatie vallen en classificeert ze naar WAF-status: volledig uitgeschakeld, alleen Detectiemodus of daadwerkelijk blokkerend. Ook wordt vastgelegd welke CRS-versie en firewallmodus wordt gebruikt en of de gateway is gekoppeld aan een centraal WAF-beleid of een lokale configuratie. De resultaten worden gebundeld in een rapport of dashboard dat voor CISO, architectuurboard en SOC inzichtelijk maakt waar risico's en verbeterkansen liggen. Dit voorkomt dat na reorganisaties, migraties of nieuwe projecten ongemerkt gateways worden uitgerold zonder WAF of met achterstallige configuraties.

Een tweede pijler van beheer is de inhoudelijke analyse van WAF-logs. Alle diagnostische gegevens van Application Gateway, waaronder access logs en WAF logs, worden verplicht weggeschreven naar een centrale Log Analytics-workspace. Hierop worden Kusto-query's en dashboards ingericht die inzicht geven in geblokkeerde en toegestane verzoeken, trends in aanvalstypen, herkomstlanden en betrokken IP-adressen. Het SOC definieert drempelwaarden voor alerts, bijvoorbeeld bij een plotselinge toename van SQL-injectiepogingen, massale requests naar specifieke inlog- of beheerroutes of het herhaaldelijk triggeren van blokkades vanaf dezelfde bron. Deze alerts leiden tot incidenttickets en runbooks waarin is vastgelegd welke acties de analist moet ondernemen: aanvullende blokkades configureren, applicatie-eigenaren informeren, forensische data veiligstellen of escaleren naar landelijke partijen zoals het Nationaal Cyber Security Centrum. Door WAF-logs consequent te analyseren, ontstaat een rijk beeld van de dreigingsomgeving en kunnen maatregelen tijdig worden aangescherpt.

Tuning vormt de derde pijler en voorkomt dat WAF-configuratie na verloop van tijd verstijft of juist langzaam wordt uitgehold. Nieuwe functionaliteit, wijzigingen in gebruikersgedrag en veranderende dreigingen zorgen ervoor dat beleid periodiek moet worden herzien. De Nederlandse Baseline voor Veilige Cloud adviseert minimaal kwartaalgewijs een tuningcyclus uit te voeren, waarin loganalyses worden gebruikt om false positives en onbenutte regels te identificeren. Voor elke regel of uitzondering wordt beoordeeld of deze nog nodig is, of dat de scope kan worden verkleind of uitgebreid. Tevens worden lessons learned uit incidenten vertaald naar nieuwe custom rules of strengere drempels. Door tuningproces te koppelen aan formele changeprocedures en security governance, wordt voorkomen dat individuele beheerders op eigen initiatief brede uitzonderingen toevoegen die de effectiviteit van WAF ondermijnen.

Naast technische monitoring en tuning zijn heldere verantwoordelijkheden en rapportages essentieel. Organisaties leggen vast wie optreedt als product owner voor Application Gateway WAF, welke teams de dagelijkse operatie verzorgen en hoe afstemming plaatsvindt met ontwikkelteams en business-eigenaren. Periodieke rapportages – bijvoorbeeld maandelijks of per kwartaal – bevatten kerncijfers zoals het aantal geblokkeerde aanvallen, verdeling naar type, tijd tot mitigatie van geconstateerde kwetsbaarheden en het percentage gateways dat volledig aan het standaardbeleid voldoet. Deze rapportages worden besproken in security- en risicocomités en vormen input voor strategische keuzes, zoals uitbreiding van capaciteit, investering in aanvullende tooling of verscherping van acceptatiecriteria voor nieuwe applicaties. Zo groeit Application Gateway WAF uit tot een volwaardige beveiligingsdienst in plaats van een losstaande technische component.

Compliance & Frameworks

Automation

Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).

PowerShell
<# ================================================================================ AZURE POWERSHELL SCRIPT - Nederlandse Baseline voor Veilige Cloud ================================================================================ .SYNOPSIS Azure Application Gateway: WAF configuratiecontrole .DESCRIPTION Voert een lichte beoordeling uit van de Web Application Firewall (WAF) configuratie op Azure Application Gateways. Het script inventariseert: - Of WAF is ingeschakeld - In welke modus WAF draait (Detection of Prevention) - Welke OWASP Core Rule Set (CRS) versie is geconfigureerd - Of een WAF-beleid is gekoppeld - Of diagnostische logging is ingeschakeld Dit script wijzigt GEEN resources en is bedoeld als ondersteunende controle voor het artikel 'Azure Application Gateway: Web Application Firewall (WAF) configuratie' binnen de Nederlandse Baseline voor Veilige Cloud. .NOTES Filename: waf-configuration.ps1 Author: Nederlandse Baseline voor Veilige Cloud Version: 1.0 Related JSON: content/azure/application-gateway/waf-configuration.json .PARAMETER Monitoring Toont een leesbaar overzicht van de huidige WAF-configuratie per Application Gateway in de console. .EXAMPLE .\waf-configuration.ps1 Voert een basiscontrole uit en retourneert een object met resultaten. .EXAMPLE .\waf-configuration.ps1 -Monitoring Voert de controle uit en toont een samenvatting in de console. #> #Requires -Version 5.1 #Requires -Modules Az.Accounts, Az.Network [CmdletBinding()] param( [Parameter()][switch]$Monitoring ) $ErrorActionPreference = 'Stop' $PolicyName = "Azure Application Gateway: WAF configuratie" function Connect-RequiredServices { if (-not (Get-AzContext -ErrorAction SilentlyContinue)) { Connect-AzAccount | Out-Null } } function Get-WafConfigurationSummary { <# .SYNOPSIS Haalt een overzicht op van WAF-configuratie voor alle Application Gateways. .OUTPUTS PSCustomObject per Application Gateway met WAF-status en kerninstellingen. #> [CmdletBinding()] param() $gateways = Get-AzApplicationGateway -ErrorAction SilentlyContinue if (-not $gateways) { return @() } $results = @() foreach ($gw in $gateways) { $wafConfig = $gw.WebApplicationFirewallConfiguration $wafEnabled = $false $wafMode = $null $ruleSetType = $null $ruleSetVer = $null $policyId = $null if ($wafConfig) { $wafEnabled = [bool]$wafConfig.Enabled $wafMode = $wafConfig.FirewallMode $ruleSetType = $wafConfig.RuleSetType $ruleSetVer = $wafConfig.RuleSetVersion if ($wafConfig.FirewallPolicy) { $policyId = $wafConfig.FirewallPolicy.Id } } # Diagnostische logging via diagnostic settings (optionele best effort check) $hasDiagnostics = $false try { $diag = Get-AzDiagnosticSetting -ResourceId $gw.Id -ErrorAction SilentlyContinue if ($diag) { foreach ($d in $diag) { if ($d.Logs | Where-Object { $_.Enabled -and $_.Category -like '*ApplicationGateway*' }) { $hasDiagnostics = $true break } } } } catch { # Loggingcontrole is best effort; geen harde fout als dit mislukt. } $results += [PSCustomObject]@{ Name = $gw.Name ResourceGroup = $gw.ResourceGroupName Location = $gw.Location SkuName = $gw.Sku.Name SkuTier = $gw.Sku.Tier WafEnabled = $wafEnabled WafMode = $wafMode RuleSetType = $ruleSetType RuleSetVersion = $ruleSetVer FirewallPolicyId = $policyId HasDiagnosticsLogs = $hasDiagnostics } } return $results } function Test-Compliance { <# .SYNOPSIS Berekent een eenvoudige compliance-samenvatting voor WAF-configuratie. .OUTPUTS PSCustomObject met totalen en detailrecords. #> [CmdletBinding()] param() $summary = [PSCustomObject]@{ PolicyName = $PolicyName TotalGateways = 0 WafEnabledCount = 0 PreventionModeCount = 0 DetectionModeCount = 0 NoWafCount = 0 MissingDiagnostics = 0 Gateways = @() } $gateways = Get-WafConfigurationSummary if (-not $gateways -or $gateways.Count -eq 0) { return $summary } $gateways = @($gateways) $summary.TotalGateways = $gateways.Count $summary.Gateways = $gateways foreach ($g in $gateways) { if ($g.WafEnabled) { $summary.WafEnabledCount++ if ($g.WafMode -eq 'Prevention') { $summary.PreventionModeCount++ } elseif ($g.WafMode -eq 'Detection') { $summary.DetectionModeCount++ } } else { $summary.NoWafCount++ } if (-not $g.HasDiagnosticsLogs) { $summary.MissingDiagnostics++ } } return $summary } try { Connect-RequiredServices if ($Monitoring) { $r = Test-Compliance Write-Host "`n========================================" -ForegroundColor Cyan Write-Host $PolicyName -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan if ($r.TotalGateways -eq 0) { Write-Host "Geen Application Gateways gevonden in de huidige context." -ForegroundColor Yellow } else { Write-Host ("Totaal Application Gateways : {0}" -f $r.TotalGateways) -ForegroundColor White Write-Host ("Met WAF ingeschakeld : {0}" -f $r.WafEnabledCount) -ForegroundColor (if ($r.WafEnabledCount -gt 0) { 'Green' } else { 'Yellow' }) Write-Host ("In Prevention modus : {0}" -f $r.PreventionModeCount) -ForegroundColor (if ($r.PreventionModeCount -gt 0) { 'Green' } else { 'Yellow' }) Write-Host ("Alleen Detection modus : {0}" -f $r.DetectionModeCount) -ForegroundColor Yellow Write-Host ("Zonder WAF : {0}" -f $r.NoWafCount) -ForegroundColor (if ($r.NoWafCount -gt 0) { 'Red' } else { 'Green' }) Write-Host ("Zonder diagnostische logs : {0}" -f $r.MissingDiagnostics) -ForegroundColor (if ($r.MissingDiagnostics -gt 0) { 'Yellow' } else { 'Green' }) if ($r.Gateways.Count -gt 0) { Write-Host "`nDetails per gateway:" -ForegroundColor Yellow foreach ($g in $r.Gateways) { $status = if ($g.WafEnabled) { $g.WafMode } else { 'Disabled' } Write-Host ("- {0} (RG: {1}) - WAF: {2}, CRS: {3} {4}, Diagnostics: {5}" -f ` $g.Name, $g.ResourceGroup, $status, $g.RuleSetType, $g.RuleSetVersion, ` (if ($g.HasDiagnosticsLogs) { 'Ja' } else { 'Nee' })) -ForegroundColor Gray } } } } else { Test-Compliance } } catch { Write-Error $_ exit 1 } # ================================================================================ # Standaard Invoke-* functies voor integratie met content-artikelen # ================================================================================ function Invoke-Assessment { <# .SYNOPSIS Geeft een gedetailleerde beoordeling van de WAF-configuratie terug. .OUTPUTS PSCustomObject met summary en details per gateway. #> [CmdletBinding()] param() Connect-RequiredServices return Test-Compliance } function Invoke-Monitoring { <# .SYNOPSIS Voert de monitoringweergave uit zoals beschreven in het artikel. #> [CmdletBinding()] param() $Monitoring = $true try { Connect-RequiredServices $r = Test-Compliance Write-Host "`n========================================" -ForegroundColor Cyan Write-Host $PolicyName -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan if ($r.TotalGateways -eq 0) { Write-Host "Geen Application Gateways gevonden in de huidige context." -ForegroundColor Yellow } else { Write-Host ("Totaal Application Gateways : {0}" -f $r.TotalGateways) -ForegroundColor White Write-Host ("Met WAF ingeschakeld : {0}" -f $r.WafEnabledCount) -ForegroundColor (if ($r.WafEnabledCount -gt 0) { 'Green' } else { 'Yellow' }) Write-Host ("In Prevention modus : {0}" -f $r.PreventionModeCount) -ForegroundColor (if ($r.PreventionModeCount -gt 0) { 'Green' } else { 'Yellow' }) Write-Host ("Alleen Detection modus : {0}" -f $r.DetectionModeCount) -ForegroundColor Yellow Write-Host ("Zonder WAF : {0}" -f $r.NoWafCount) -ForegroundColor (if ($r.NoWafCount -gt 0) { 'Red' } else { 'Green' }) Write-Host ("Zonder diagnostische logs : {0}" -f $r.MissingDiagnostics) -ForegroundColor (if ($r.MissingDiagnostics -gt 0) { 'Yellow' } else { 'Green' }) if ($r.Gateways.Count -gt 0) { Write-Host "`nDetails per gateway:" -ForegroundColor Yellow foreach ($g in $r.Gateways) { $status = if ($g.WafEnabled) { $g.WafMode } else { 'Disabled' } Write-Host ("- {0} (RG: {1}) - WAF: {2}, CRS: {3} {4}, Diagnostics: {5}" -f ` $g.Name, $g.ResourceGroup, $status, $g.RuleSetType, $g.RuleSetVersion, ` (if ($g.HasDiagnosticsLogs) { 'Ja' } else { 'Nee' })) -ForegroundColor Gray } } } return $r } catch { Write-Error $_ exit 1 } } function Invoke-Implementation { <# .SYNOPSIS Placeholder voor implementatie-automatisering. .DESCRIPTION Dit script voert geen automatische remediatie uit. Gebruik de output van Invoke-Assessment en Invoke-Monitoring om verbeteracties te definiëren in change- en implementatieprocessen. #> [CmdletBinding()] param() Write-Host "[INFO] Dit script voert geen automatische implementatie uit." -ForegroundColor Yellow Write-Host "[INFO] Gebruik Invoke-Assessment of Invoke-Monitoring voor een actuele status." -ForegroundColor Yellow } function Invoke-Remediation { <# .SYNOPSIS Ondersteunende functie voor remediatie. .DESCRIPTION Biedt dezelfde informatie als Invoke-Monitoring, zodat beheerders gericht kunnen bepalen welke Application Gateways moeten worden aangepast. Wijzigingen aan WAF-configuratie worden altijd via afzonderlijke change-scripts of IaC-templates uitgevoerd. #> [CmdletBinding()] param() Write-Host "[INFO] Dit is een read-only remediatie-ondersteuningsscript." -ForegroundColor Yellow Invoke-Monitoring | Out-Null } <# ================================================================================ AZURE POWERSHELL SCRIPT - Nederlandse Baseline voor Veilige Cloud ================================================================================ .SYNOPSIS Controle en basisanalyse van WAF-configuratie op Azure Application Gateways. .DESCRIPTION Dit script controleert of Azure Application Gateways zijn voorzien van een Web Application Firewall (WAF)-configuratie die voldoet aan de minimale eisen van de Nederlandse Baseline voor Veilige Cloud: - Alle internetgerichte Application Gateways hebben een gekoppelde WAF-policy - WAF draait niet uitsluitend in Detection mode in productieomgevingen - Er is ten minste één actieve OWASP-regelset geconfigureerd Het script voert GEEN automatische remediatie uit, maar geeft een duidelijk overzicht en concrete aanbevelingen voor vervolgacties. .NOTES Filename: waf-configuration.ps1 Author: Nederlandse Baseline voor Veilige Cloud Version: 1.0 Related JSON: content/azure/application-gateway/waf-configuration.json .EXAMPLE .\waf-configuration.ps1 -Monitoring Voert een controle uit op alle Application Gateways in de huidige context en toont een overzicht van WAF-configuratie en eventuele tekortkomingen. #> #Requires -Version 5.1 #Requires -Modules Az.Accounts, Az.Network [CmdletBinding()] param( [Parameter()] [switch]$WhatIf, [Parameter()] [switch]$Monitoring, [Parameter()] [switch]$Remediation ) $ErrorActionPreference = 'Stop' $VerbosePreference = 'Continue' $PolicyName = "Azure Application Gateway WAF-configuratie" $ScriptName = "waf-configuration.ps1" function Connect-RequiredServices { <# .SYNOPSIS Maakt verbinding met Azure voor netwerkbeheer. #> [CmdletBinding()] param() if (-not (Get-AzContext -ErrorAction SilentlyContinue)) { Write-Verbose "Geen actieve Az-context gevonden. Verbinden met Azure..." Connect-AzAccount -ErrorAction Stop | Out-Null } } function Get-WafConfigurationStatus { <# .SYNOPSIS Haalt WAF-status op voor alle Application Gateways. .OUTPUTS PSCustomObject[] #> [CmdletBinding()] param() Write-Verbose "Ophalen van Application Gateways..." $gateways = Get-AzApplicationGateway -ErrorAction SilentlyContinue if (-not $gateways) { Write-Verbose "Geen Application Gateways gevonden in de huidige context." return @() } $results = @() foreach ($gw in $gateways) { $isPublic = $false if ($gw.FrontendIPConfigurations) { $isPublic = $gw.FrontendIPConfigurations | Where-Object { $_.PublicIPAddress -ne $null } | ForEach-Object { $true } | Select-Object -First 1 if (-not $isPublic) { $isPublic = $false } } $wafConfig = $gw.WebApplicationFirewallConfiguration $wafEnabled = $false $wafMode = $null $ruleSetType = $null $ruleSetVer = $null if ($wafConfig) { $wafEnabled = [bool]$wafConfig.Enabled $wafMode = $wafConfig.FirewallMode $ruleSetType = $wafConfig.RuleSetType $ruleSetVer = $wafConfig.RuleSetVersion } $results += [PSCustomObject]@{ Name = $gw.Name ResourceGroup = $gw.ResourceGroupName Location = $gw.Location IsPublic = [bool]$isPublic WafEnabled = $wafEnabled WafMode = $wafMode RuleSetType = $ruleSetType RuleSetVer = $ruleSetVer } } return $results } function Test-Compliance { <# .SYNOPSIS Bepaalt compliance-status voor WAF-configuratie op Application Gateways. .OUTPUTS PSCustomObject #> [CmdletBinding()] param() $status = Get-WafConfigurationStatus if (-not $status) { return [PSCustomObject]@{ ScriptName = $ScriptName IsCompliant = $true Timestamp = Get-Date Details = "Geen Application Gateways gevonden in de huidige context." Recommendations = @() AffectedObjects = @() } } $nonCompliant = @() $recommendations = @() foreach ($g in $status) { if ($g.IsPublic -and -not $g.WafEnabled) { $nonCompliant += $g $recommendations += "Application Gateway '$($g.Name)' in resourcegroep '$($g.ResourceGroup)' is publiek bereikbaar maar heeft WAF niet ingeschakeld." } elseif ($g.IsPublic -and $g.WafEnabled -and $g.WafMode -eq "Detection") { $nonCompliant += $g $recommendations += "Application Gateway '$($g.Name)' in resourcegroep '$($g.ResourceGroup)' heeft WAF alleen in Detection-modus. Overweeg Prevent-modus na tuning." } elseif ($g.IsPublic -and $g.WafEnabled -and -not $g.RuleSetType) { $nonCompliant += $g $recommendations += "Application Gateway '$($g.Name)' heeft WAF ingeschakeld maar geen OWASP-regelset geconfigureerd." } } $isCompliant = ($nonCompliant.Count -eq 0) if (-not $recommendations) { $recommendations = @("Alle gevonden Application Gateways voldoen aan de minimale WAF-configuratie-eisen van deze control.") } return [PSCustomObject]@{ ScriptName = $ScriptName IsCompliant = $isCompliant Timestamp = Get-Date Details = if ($isCompliant) { "Alle publiek toegankelijke Application Gateways hebben een basis WAF-configuratie." } else { "Een of meer Application Gateways voldoen niet aan de minimale WAF-configuratie-eisen." } Recommendations = $recommendations | Select-Object -Unique AffectedObjects = $nonCompliant } } function Invoke-Monitoring { <# .SYNOPSIS Voert een monitoringrun uit en toont overzichtelijke resultaten. #> [CmdletBinding()] param() Connect-RequiredServices Write-Host "" -ForegroundColor White Write-Host "========================================" -ForegroundColor Cyan Write-Host $PolicyName -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan $result = Test-Compliance Write-Host ("Tijdstip : {0}" -f $result.Timestamp) -ForegroundColor White Write-Host ("Compliant : {0}" -f $result.IsCompliant) -ForegroundColor (if ($result.IsCompliant) { 'Green' } else { 'Yellow' }) Write-Host ("Details : {0}" -f $result.Details) -ForegroundColor White Write-Host "" -ForegroundColor White if ($result.AffectedObjects -and $result.AffectedObjects.Count -gt 0) { Write-Host "Niet-conforme Application Gateways:" -ForegroundColor Yellow foreach ($g in $result.AffectedObjects) { Write-Host (" - {0} (RG: {1}, Locatie: {2}, Public: {3}, WAF Enabled: {4}, Mode: {5}, RuleSet: {6} {7})" -f ` $g.Name, $g.ResourceGroup, $g.Location, $g.IsPublic, $g.WafEnabled, $g.WafMode, $g.RuleSetType, $g.RuleSetVer) -ForegroundColor Yellow } Write-Host "" -ForegroundColor White } Write-Host "Aanbevelingen:" -ForegroundColor Cyan foreach ($rec in $result.Recommendations) { Write-Host (" - {0}" -f $rec) -ForegroundColor White } if ($result.IsCompliant) { exit 0 } else { exit 1 } } function Invoke-Remediation { <# .SYNOPSIS Geeft remediatie-advies voor WAF-configuratie. .DESCRIPTION Dit script voert bewust GEEN automatische wijzigingen uit aan Application Gateways of WAF-policies. In plaats daarvan wordt een overzicht gegeven van noodzakelijke acties die door beheerders moeten worden opgepakt via Infrastructure as Code of changeprocedures. #> [CmdletBinding()] param() Connect-RequiredServices $result = Test-Compliance Write-Host "" -ForegroundColor White Write-Host "Remediatie-aanpak voor: $PolicyName" -ForegroundColor Cyan Write-Host "============================================================" -ForegroundColor Cyan if ($result.IsCompliant) { Write-Host "Alle gecontroleerde Application Gateways voldoen aan de minimale WAF-eisen." -ForegroundColor Green Write-Host "Geen directe remediatie-acties noodzakelijk." -ForegroundColor Green exit 0 } Write-Host "Niet-conforme configuraties zijn gedetecteerd. Voer de volgende stappen uit:" -ForegroundColor Yellow Write-Host "" -ForegroundColor White foreach ($rec in $result.Recommendations) { Write-Host (" - {0}" -f $rec) -ForegroundColor Yellow } Write-Host "" -ForegroundColor White Write-Host "Let op: Pas wijzigingen bij voorkeur toe via Infrastructure as Code" -ForegroundColor Yellow Write-Host " (Bicep/ARM/Terraform) en borg change- en reviewprocedures." -ForegroundColor Yellow if ($WhatIf) { Write-Host "" -ForegroundColor White Write-Host "[WhatIf] Er zijn geen wijzigingen doorgevoerd. Gebruik deze output als input voor een change." -ForegroundColor Yellow } exit 1 } try { if ($Monitoring -or (-not $Monitoring -and -not $Remediation)) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } } catch { Write-Error ("Er is een fout opgetreden in {0}: {1}" -f $ScriptName, $_) exit 2 }

Risico zonder implementatie

Risico zonder implementatie
Critical: Zonder een correct geconfigureerde WAF op Azure Application Gateway zijn webapplicaties direct kwetsbaar voor OWASP Top 10-aanvallen, zero-day exploits in frameworks en misbruik van configuratiefouten. Aanvallers kunnen relatief eenvoudig SQL-injectie, XSS of RCE proberen totdat één kwetsbaar endpoint wordt gevonden, met mogelijke datalekken, verstoring van essentiële overheidsdiensten en reputatieschade tot gevolg. Daarnaast ontbreekt zonder WAF centraal inzicht in aanvalspatronen en ontbreekt essentieel bewijsmateriaal voor forensisch onderzoek en naleving van BIO, NIS2 en AVG. In audits zal het ontbreken van WAF bij internetgerichte applicaties worden gezien als een structurele tekortkoming in de technische beveiligingsmaatregelen.

Management Samenvatting

Azure Application Gateway met Web Application Firewall (WAF) vormt een verplichte verdedigingslaag voor internetgerichte webapplicaties binnen de Nederlandse Baseline voor Veilige Cloud. Door een gestandaardiseerde architectuur, modern WAF-beleid op basis van OWASP CRS en strakke integratie met Log Analytics en SOC-processen te implementeren, worden aanvallen vroegtijdig geblokkeerd en wordt een rijk beeld van dreigingen opgebouwd. Het bijbehorende PowerShell-script inventariseert automatisch welke Application Gateways WAF hebben ingeschakeld, in welke modus zij draaien en of logging en moderne regels actief zijn, zodat hiaten snel zichtbaar worden. De benodigde inspanning is beperkt (circa 32 uur initiële implementatie), terwijl de risicoreductie en auditbaarheid aanzienlijk zijn voor alle webgebaseerde diensten in Azure.