Azure App Service: Web Application Firewall Configuratie

💼 Management Samenvatting

Azure App Service-applicaties die direct via internet toegankelijk zijn, vormen een aantrekkelijk doelwit voor geautomatiseerde aanvallen, botnets en doelgerichte exploitatiepogingen. Een Web Application Firewall (WAF) die vóór App Service wordt geplaatst, vormt een essentiële verdedigingslaag die kwaadaardig verkeer onderschept en blokkeert voordat het de applicatie bereikt. Voor Nederlandse overheidsorganisaties is het implementeren van WAF-beveiliging niet alleen een security best practice, maar ook een vereiste voor compliance met BIO, NIS2 en andere kaders die defense-in-depth-principes voorschrijven.

Aanbeveling
IMPLEMENTEER WAF-BESCHERMING VOOR ALLE INTERNETGERICHTE APP SERVICES
Risico zonder
Critical
Risk Score
9/10
Implementatie
24u (tech: 16u)
Van toepassing op:
Azure App Service
Azure Application Gateway
Azure Front Door

Azure App Service-applicaties zijn standaard direct toegankelijk via internet via hun standaard hostname (*.azurewebsites.net) en eventuele aangepaste domeinen. Dit betekent dat elke applicatie automatisch wordt blootgesteld aan continue scanactiviteiten, automatische exploitpogingen en gerichte aanvallen die zoeken naar kwetsbaarheden zoals SQL-injectie, Cross-Site Scripting (XSS), Command Injection en andere OWASP Top 10-risico's. Zonder WAF-bescherming worden deze aanvallen direct gericht op de applicatielaag, waardoor ontwikkelteams constant alert moeten zijn op nieuwe kwetsbaarheden en patches moeten uitrollen voordat exploits kunnen worden misbruikt. Dit is onhoudbaar in een omgeving waar applicaties continu worden geüpdatet en waar legacy-componenten naast moderne microservices draaien. Bovendien biedt WAF niet alleen bescherming tegen bekende aanvalspatronen, maar ook tegen volumetrische aanvallen zoals DDoS-pogingen op applicatieniveau, brute-force aanvallen op inlogpagina's en geautomatiseerde scraping-activiteiten die de beschikbaarheid en prestaties van diensten kunnen beïnvloeden. WAF-logboeken vormen daarnaast een rijke bron van threat intelligence: zij tonen welke endpoints worden aangevallen, welke payloads worden gebruikt en of er sprake is van georganiseerde campagnes. Deze informatie is onmisbaar voor forensisch onderzoek na incidenten en voor het bewijs aan toezichthouders dat proactieve beveiligingsmaatregelen zijn genomen. Voor Nederlandse overheidsorganisaties speelt compliance een cruciale rol. Frameworks zoals BIO, ISO 27001 en NIS2 vereisen expliciet dat organisaties defense-in-depth-maatregelen implementeren, waarbij meerdere beveiligingslagen elkaar aanvullen. WAF vormt een aantoonbare control die auditors kunnen verifiëren en die bewijst dat de organisatie redelijke maatregelen heeft genomen om applicaties te beschermen. Het ontbreken van WAF-bescherming kan leiden tot auditbevindingen, compliance-problemen en zelfs bestuurlijke aansprakelijkheid wanneer een incident had kunnen worden voorkomen met standaard beveiligingsmaatregelen.

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

Implementatie

Dit artikel beschrijft een volledig raamwerk voor het implementeren en configureren van Web Application Firewall-bescherming voor Azure App Service binnen de context van de Nederlandse Baseline voor Veilige Cloud. De aanpak omvat het selecteren van de juiste WAF-oplossing (Azure Application Gateway met WAF_v2 of Azure Front Door Premium met geïntegreerde WAF), het ontwerpen en configureren van WAF-beleid met OWASP Core Rule Set 3.2 of hoger, het implementeren van rate limiting en geo-filtering voor specifieke use cases, het instellen van detectie- en preventiemodi met geleidelijke activering, en het configureren van uitgebreide logging en monitoring die alle WAF-activiteiten vastlegt voor security operations en audit doeleinden. De implementatie begint met de architecturale keuze tussen Application Gateway en Front Door. Application Gateway is ideaal voor regionale scenario's waarbij App Services in één of meerdere Azure-regio's draaien en waarbij Layer 7-loadbalancing en SSL-terminatie nodig zijn. Front Door is de juiste keuze voor globale diensten waarbij gebruikers wereldwijd verspreid zijn en waarbij edge-caching en snelle failover essentieel zijn. Beide oplossingen bieden WAF-capaciteiten, maar de configuratie en integratie met App Service verschilt. Een cruciaal onderdeel van de implementatie is het configureren van WAF-regels en uitzonderingen die zijn afgestemd op de specifieke behoeften van App Service-applicaties. Dit omvat het activeren van OWASP-regelsets voor basisbescherming, het toevoegen van custom regels voor applicatie-specifieke bedreigingen, het configureren van uitzonderingen voor legitiem verkeer (bijvoorbeeld voor specifieke user agents, IP-adressen of API-paden), en het instellen van rate limiting-regels die voorkomen dat individuele gebruikers of IP-adressen de applicatie kunnen overbelasten. Alle configuraties worden eerst uitgerold in Detectiemodus zodat logs inzicht geven in vals-positieve signalen voordat blokkerende regels worden geactiveerd. Monitoring en logging vormen de ruggengraat van effectieve WAF-operaties. Alle WAF-telemetrie wordt gestreamd naar Azure Log Analytics waar queries en alerts worden geconfigureerd voor het detecteren van aanvalspatronen, volumetrische dreigingen en compliance-rapportage. Het artikel bevat praktische implementatiegidsen voor elk onderdeel, inclusief PowerShell-scripts voor monitoring en configuratiecontroles, en beschrijft hoe deze praktijken aansluiten bij BIO-controles voor applicatiebeveiliging en ISO 27001-vereisten voor runtime-bescherming.

Architectuurkeuze: Application Gateway versus Front Door voor App Service

De keuze tussen Azure Application Gateway met WAF_v2 en Azure Front Door Premium met WAF is fundamenteel voor de architectuur van beveiligde App Service-omgevingen. Beide oplossingen bieden robuuste WAF-capaciteiten, maar zijn geoptimaliseerd voor verschillende scenario's en hebben verschillende integratiepatronen met App Service. Nederlandse overheidsorganisaties moeten deze keuze zorgvuldig afwegen op basis van hun specifieke vereisten voor geografische spreiding, prestaties, kosten en beheerbaarheid. Azure Application Gateway met WAF_v2 is de aangewezen oplossing voor regionale of multi-regionale scenario's waarbij App Services voornamelijk draaien binnen één of meerdere Azure-regio's. De gateway fungeert als een reverse proxy op Layer 7 die verkeer ontvangt, analyseert en doorstuurt naar backend App Services. Een belangrijk voordeel van Application Gateway is de naadloze integratie met App Service via de App Service Environment (ASE) of via standaard App Service met private endpoints. Wanneer App Services zijn geconfigureerd met private endpoints, kan Application Gateway verkeer routeren via het virtuele netwerk zonder dat publieke internettoegang nodig is voor de App Service zelf. Dit versterkt het security-posture door de App Service te isoleren van direct internetverkeer terwijl WAF-bescherming op de gateway wordt uitgevoerd. Application Gateway biedt daarnaast geavanceerde routing-capaciteiten die specifiek nuttig zijn voor App Service-omgevingen. Path-based routing maakt het mogelijk om verschillende paden naar verschillende App Services te routeren, wat handig is voor microservices-architecturen waar meerdere App Services achter één gateway draaien. Multi-site hosting stelt organisaties in staat om meerdere domeinen en SSL-certificaten te beheren via één gateway, wat de beheerbaarheid verbetert. De integratie met Azure Key Vault voor SSL-certificaatbeheer maakt het mogelijk om certificaten centraal te beheren en automatisch te roteren zonder downtime. Voor organisaties die al gebruikmaken van Application Gateway voor loadbalancing of SSL-terminatie, is het toevoegen van WAF-beleid een logische volgende stap die minimale architecturale wijzigingen vereist.

Azure Front Door Premium met WAF is daarentegen geoptimaliseerd voor globale, internetgerichte diensten waarbij gebruikers wereldwijd verspreid zijn en waarbij edge-optimalisatie en snelle failover essentieel zijn. Front Door opereert op het Microsoft-global edge-netwerk, wat betekent dat verkeer dicht bij gebruikers wordt afgehandeld voordat het wordt doorgestuurd naar App Services in Azure-regio's. Deze architectuur biedt inherente bescherming tegen DDoS-aanvallen op het edge-netwerk en levert betere prestaties voor gebruikers buiten de primaire Azure-regio's door middel van edge-caching en route-optimalisatie. Voor App Services die diensten leveren aan burgers verspreid over Nederland of zelfs internationaal, kan Front Door significante performance-voordelen opleveren. Een belangrijk onderscheid tussen Application Gateway en Front Door is de manier waarop zij met App Service integreren. Front Door gebruikt standaard publieke endpoints van App Services (via de *.azurewebsites.net hostname of aangepaste domeinen), wat betekent dat App Services direct toegankelijk blijven via internet, zij het met WAF-bescherming op het edge. Dit kan worden gecombineerd met App Service-toegangsbeperkingen (IP-restricties) die alleen verkeer van Front Door-backend-IP-adressen toestaan, maar dit vereist onderhoud van IP-lijsten. Application Gateway daarentegen kan volledig private endpoints gebruiken wanneer App Services in een Virtual Network zijn geïntegreerd, wat een sterkere isolatie biedt. De kostenstructuur verschilt ook aanzienlijk tussen beide oplossingen. Application Gateway wordt gefactureerd op basis van gateway-capaciteit, aantal verwerkte gegevens en WAF-features. Voor regionale scenario's met voorspelbaar verkeer is dit vaak kosteneffectiever. Front Door Premium wordt gefactureerd op basis van verwerkte gegevens en edge-requests, wat voordeliger kan zijn voor diensten met veel cacheable content maar duurder voor dynamische applicaties met veel edge-traffic. Organisaties moeten hun verkeerspatronen analyseren en kostenramingen maken voor beide scenario's voordat een definitieve keuze wordt gemaakt.

Voor Nederlandse overheidsorganisaties zijn er ook compliance-overwegingen die de keuze kunnen beïnvloeden. Beide oplossingen voldoen aan de vereisten voor WAF-bescherming zoals beschreven in BIO en ISO 27001, maar de manier waarop logging en audit-evidence worden vastgelegd verschilt. Application Gateway-logs kunnen rechtstreeks worden gestreamd naar Log Analytics-workspaces binnen dezelfde regio, wat belangrijk kan zijn voor data-residency-vereisten. Front Door-logs worden centraal beheerd op het edge-netwerk en moeten worden geëxporteerd naar Azure-regio's voor langdurige retentie. Organisaties moeten hun data-residency-beleid en compliance-vereisten tegen deze logboekarchitecturen afzetten om te bepalen welke oplossing het beste past. Tot slot is er de beheerbaarheid en operationele complexiteit. Application Gateway vereist meer handmatige configuratie van backendpools, health probes en routingregels, wat meer expertise vereist maar ook meer controle biedt. Front Door heeft geautomatiseerde health checks en failover-capaciteiten die operationele overhead kunnen verminderen, maar kan minder flexibel zijn voor complexe routing-scenario's. De keuze tussen beide oplossingen moet daarom niet alleen gebaseerd zijn op technische vereisten, maar ook op de beschikbare expertise binnen de organisatie en de gewenste balans tussen automatisering en controle.

WAF-beleid configureren met OWASP-regelsets en custom regels

Het configureren van effectief WAF-beleid voor Azure App Service-applicaties vereist een gefaseerde aanpak die begint met standaard OWASP-regelsets en geleidelijk wordt uitgebreid met custom regels die zijn afgestemd op de specifieke risico's en vereisten van de applicatie. Het beleid moet een balans vinden tussen bescherming tegen bekende bedreigingen en het voorkomen van vals-positieve signalen die legitiem verkeer blokkeren en de gebruikerservaring beïnvloeden. Voor Nederlandse overheidsorganisaties is het essentieel dat WAF-configuraties niet alleen technisch effectief zijn, maar ook aantoonbaar en controleerbaar voor audit doeleinden. De basis van elk WAF-beleid wordt gevormd door de OWASP Core Rule Set (CRS), momenteel versie 3.2 of hoger. Deze regelset bevat honderden regels die bescherming bieden tegen de OWASP Top 10-risico's, waaronder SQL-injectie, Cross-Site Scripting (XSS), Remote File Inclusion, Command Injection, Path Traversal en vele andere bekende aanvalsvectoren. De CRS is door de OWASP-community uitgebreid getest en onderhouden, wat betekent dat organisaties kunnen vertrouwen op bewezen bescherming zonder dat zij elke regel zelf hoeven te ontwikkelen en te onderhouden. Voor App Service-applicaties wordt aanbevolen om de volledige CRS te activeren, tenzij specifieke regels conflicteren met legitiem verkeer, in welk geval uitzonderingen kunnen worden geconfigureerd.

De implementatie van WAF-beleid begint altijd met de Detectiemodus, waarbij regels worden geëvalueerd en gelogd maar verkeer niet wordt geblokkeerd. Deze fase is cruciaal omdat zij inzicht geeft in welke aanvallen worden gedetecteerd, welke regels mogelijk vals-positieve signalen genereren voor legitiem verkeer, en hoe het verkeerspatroon eruitziet onder normale omstandigheden. Tijdens de detectiefase moeten applicatie-eigenaren, ontwikkelaars en security-teams nauw samenwerken om WAF-logs te analyseren, aanvallen te identificeren en potentiële problemen te spotten voordat blokkerende regels worden geactiveerd. Deze analyseperiode moet minimaal één tot twee weken duren om een representatief beeld te krijgen van verkeerspatronen, vooral voor applicaties met seizoensgebonden of variabel gebruik. Na de detectiefase wordt overgegaan naar Preventiemodus voor specifieke regels of regelgroepen. Deze overgang gebeurt stapsgewijs, te beginnen met de regels met de laagste kans op vals-positieve signalen (zoals bekende exploit-patterns) en geleidelijk uitbreidend naar regels die mogelijk legitiem verkeer kunnen raken. Voor elke regel die wordt geactiveerd in Preventiemodus moet worden gedocumenteerd waarom deze activatie nodig is, welke uitzonderingen zijn geconfigureerd, en welke tests zijn uitgevoerd om te verifiëren dat legitiem verkeer niet wordt geblokkeerd. Deze documentatie is essentieel voor audit doeleinden en voor het onderhouden van WAF-configuraties wanneer applicaties worden bijgewerkt of nieuwe functionaliteit wordt toegevoegd.

Naast standaard OWASP-regels moeten organisaties custom regels ontwikkelen die specifiek zijn voor hun App Service-applicaties en de risico's die deze applicaties lopen. Custom regels kunnen worden gebruikt om rate limiting te implementeren voor specifieke endpoints (bijvoorbeeld maximum tien loginpogingen per minuut per IP-adres voor authenticatie-endpoints), om geo-filtering te configureren (bijvoorbeeld blokkeren van verkeer uit specifieke landen behalve Nederland en EU-landen), om specifieke user agents of IP-adressen te blokkeren die bekend staan om kwaadaardige activiteiten, en om bedrijfslogica-specifieke validaties uit te voeren (bijvoorbeeld het controleren van specifieke headerwaarden of queryparameters). Deze custom regels moeten worden gebaseerd op threat intelligence, historische incidentgegevens en risicoanalyses van de applicatie, en moeten regelmatig worden geëvalueerd en bijgewerkt wanneer nieuwe bedreigingen opduiken of wanneer applicaties worden gewijzigd. Uitzonderingen vormen een kritiek onderdeel van WAF-configuratie omdat zij voorkomen dat legitiem verkeer wordt geblokkeerd door regels die zijn ontworpen voor algemene patronen. Voor App Service-applicaties komen vals-positieve signalen vaak voor bij geavanceerde API's die complexe queryparameters gebruiken, bij legacy-systemen die niet-standaard headers of payloads genereren, of bij geïntegreerde systemen die geautomatiseerde requests verzenden met patronen die lijken op aanvalspayloads. Uitzonderingen moeten zo specifiek mogelijk worden geconfigureerd (bijvoorbeeld alleen voor specifieke URI-paden, specifieke headers of specifieke IP-adresbereiken) om de effectiviteit van WAF-bescherming niet te verminderen. Elke uitzondering moet worden gedocumenteerd met een duidelijke reden, een eigenaar en een reviewdatum, en moet periodiek worden geëvalueerd om te bepalen of deze nog steeds nodig is.

Het beheer van WAF-beleid moet worden geïntegreerd in het change management-proces van de organisatie. Wijzigingen aan WAF-configuraties, inclusief het activeren van nieuwe regels, het toevoegen van uitzonderingen of het aanpassen van rate limits, moeten worden gereviewd en goedgekeurd voordat zij worden geïmplementeerd. Voor productie-omgevingen wordt aanbevolen om wijzigingen eerst te testen in staging-omgevingen of via canary deployments waarbij een percentage van het verkeer wordt gerouteerd naar een nieuwe WAF-configuratie. Monitoring en alerting moeten worden geconfigureerd om onmiddellijk te waarschuwen wanneer WAF-regels significante hoeveelheden verkeer blokkeren of wanneer er ongebruikelijke patronen worden gedetecteerd, zodat problemen snel kunnen worden geïdentificeerd en opgelost voordat zij impact hebben op gebruikers of dienstverlening.

Monitoring, logging en threat intelligence voor WAF-bescherming

Gebruik PowerShell-script web-application-firewall.ps1 (functie Invoke-Monitoring) – Controleert WAF-configuratie en -status voor App Services en rapporteert over geblokkeerde aanvallen en compliance-status.

Uitgebreide monitoring en logging van WAF-activiteiten vormen de ruggengraat van effectieve security operations en zijn essentieel voor compliance-verificatie, incident response en continue verbetering van beveiligingsmaatregelen. Voor Nederlandse overheidsorganisaties is het niet alleen belangrijk dat WAF aanvallen blokkeert, maar ook dat alle activiteiten worden vastgelegd in auditbare logs die kunnen worden gebruikt om aan toezichthouders en auditors te bewijzen dat proactieve beveiligingsmaatregelen zijn genomen. Monitoring moet zowel real-time alerting als historische analyse ondersteunen om zowel reactieve incident response als proactieve threat hunting mogelijk te maken. Alle WAF-telemetrie moet worden gestreamd naar Azure Log Analytics Workspace voor centrale aggregatie, analyse en langdurige retentie. Application Gateway en Front Door genereren beide gedetailleerde logs die informatie bevatten over elke request die door WAF wordt geëvalueerd, inclusief de URI, headers, queryparameters, de actie die door WAF is ondernomen (toegestaan, geblokkeerd, gelogd), welke regels zijn geactiveerd, en details over de payload die heeft geleid tot een match. Deze logs vormen een rijke bron van threat intelligence die kan worden gebruikt om aanvalspatronen te identificeren, nieuwe bedreigingen te detecteren en de effectiviteit van WAF-configuraties te evalueren.

Kusto-queries (KQL) moeten worden ontwikkeld om specifieke use cases te ondersteunen. Voor volumetrische detectie moeten queries worden geconfigureerd die waarschuwen wanneer het aantal geblokkeerde aanvallen een drempelwaarde overschrijdt binnen een bepaalde tijdspanne (bijvoorbeeld meer dan honderd SQL-injectiepogingen in vijf minuten), wat kan wijzen op een geautomatiseerde aanvalscampagne. Voor gedragspatronen moeten queries worden ontwikkeld die herkennen wanneer meerdere aanvallen afkomstig zijn van hetzelfde IP-adres of wanneer aanvallen gericht zijn op specifieke endpoints die normaal gesproken niet worden aangevallen, wat kan wijzen op gerichte exploitatiepogingen. Voor compliance-rapportage moeten queries worden geconfigureerd die maandelijks of wekelijks samenvatten hoeveel aanvallen zijn geblokkeerd, welke typen aanvallen het meest voorkomen, en welke endpoints het meest worden aangevallen, zodat deze informatie kan worden gebruikt in managementrapportages en audit-documentatie. Real-time alerting moet worden geconfigureerd voor kritieke gebeurtenissen die onmiddellijke aandacht vereisen. Alerts moeten worden verzonden naar security operations centers (SOC), applicatie-eigenaren en management wanneer significante aanvalsvolumes worden gedetecteerd, wanneer nieuwe aanvalspatronen worden geïdentificeerd, of wanneer WAF-configuraties worden gewijzigd. Deze alerts moeten contextuele informatie bevatten zoals het type aanval, de bron-IP-adressen, de doeleindpoints en de impact, zodat security-analisten snel kunnen bepalen of escalatie nodig is. Alerts moeten worden geïntegreerd met incident response-procedures die beschrijven welke acties moeten worden ondernomen bij verschillende typen aanvallen, inclusief wanneer applicatie-eigenaren moeten worden geïnformeerd, wanneer management moet worden geëscaleerd, en wanneer externe partijen zoals de NCSC moeten worden gecontacteerd.

Threat intelligence-integratie maakt het mogelijk om WAF-configuraties proactief aan te passen op basis van nieuwe bedreigingen en aanvalspatronen. Organisaties moeten overwegen om threat intelligence-feeds te integreren die informatie leveren over bekende kwaadaardige IP-adressen, botnets en exploit-patterns, zodat deze informatie kan worden gebruikt om custom WAF-regels te creëren of bestaande regels aan te scherpen. Azure Sentinel of andere SIEM-oplossingen kunnen worden gebruikt om threat intelligence te correleren met WAF-logs, waardoor security-analisten kunnen identificeren wanneer bekende bedreigingen proberen App Service-applicaties aan te vallen, zelfs wanneer deze aanvallen worden geblokkeerd door WAF. Deze correlatie maakt het mogelijk om trends te identificeren, aanvalscampagnes te herkennen en proactieve maatregelen te nemen voordat nieuwe exploits succesvol kunnen zijn. Periodieke reviews en rapportages zijn essentieel voor het handhaven van effectieve WAF-operaties en voor compliance-verificatie. Maandelijks moeten security-teams WAF-logs analyseren om trends te identificeren, nieuwe bedreigingen te detecteren, en de effectiviteit van WAF-configuraties te evalueren. Deze analyses moeten leiden tot aanbevelingen voor het verbeteren van WAF-configuraties, het aanpassen van regels of uitzonderingen, of het implementeren van aanvullende beveiligingsmaatregelen. Jaarlijks moeten uitgebreide reviews worden uitgevoerd die de volledige WAF-strategie evalueren, inclusief de keuze tussen Application Gateway en Front Door, de effectiviteit van custom regels, en de alignement met veranderende bedreigingslandschappen en compliance-vereisten. Deze reviews moeten worden gedocumenteerd en beschikbaar zijn voor auditors die moeten kunnen verifiëren dat WAF-beveiliging structureel wordt beheerd en verbeterd.

Integratie met App Service en deployment-strategieën

De integratie van WAF met Azure App Service vereist zorgvuldige planning en configuratie om ervoor te zorgen dat verkeer correct wordt gerouteerd, dat beveiligingsmaatregelen effectief zijn, en dat de gebruikerservaring niet wordt beïnvloed door onnodige blokkades of vertragingen. De integratiepatronen verschillen tussen Application Gateway en Front Door, en organisaties moeten de juiste aanpak kiezen op basis van hun architectuur en beveiligingsvereisten. Voor Application Gateway met App Service begint de integratie met het configureren van backendpools die verwijzen naar App Service-hostnames. Wanneer App Services gebruikmaken van private endpoints binnen een Virtual Network, moet Application Gateway ook binnen hetzelfde Virtual Network worden geplaatst of verbonden via Virtual Network-peering, zodat verkeer via het private netwerk kan worden gerouteerd zonder publieke internettoegang. Voor App Services zonder private endpoints moet Application Gateway worden geconfigureerd om te verbinden met de publieke hostname, maar kunnen aanvullende beveiligingsmaatregelen worden geïmplementeerd zoals IP-restricties op App Service-niveau die alleen verkeer van Application Gateway-backend-IP-adressen toestaan. Deze aanpak vermindert het risico dat App Services direct via internet worden aangevallen, maar vereist onderhoud van IP-lijsten wanneer Application Gateway-IP-adressen veranderen.

Health probes zijn essentieel voor Application Gateway om te verifiëren dat backend App Services beschikbaar en gezond zijn. Probes moeten worden geconfigureerd om te controleren op specifieke endpoints die de gezondheid van de applicatie aangeven, niet alleen de beschikbaarheid van de App Service-infrastructuur. Voor App Services met meerdere deployment slots (bijvoorbeeld staging en production) moeten health probes worden geconfigureerd voor de productie-slot, en moeten routingregels worden ingesteld zodat alleen gezonde backends verkeer ontvangen. Wanneer een App Service gezondheidsproblemen heeft, moet Application Gateway automatisch verkeer omleiden naar alternatieve backends of een foutmelding retourneren in plaats van verkeer te blijven sturen naar een onbeschikbare applicatie. SSL/TLS-configuratie vormt een belangrijk onderdeel van de WAF-integratie omdat Application Gateway en Front Door beide SSL-terminatie kunnen uitvoeren, wat betekent dat de SSL-verbinding tussen client en gateway wordt beëindigd en een nieuwe verbinding wordt gemaakt tussen gateway en App Service. Voor optimale beveiliging moet end-to-end-encryptie worden geconfigureerd waarbij zowel de client-gateway-verbinding als de gateway-App Service-verbinding worden versleuteld. Application Gateway ondersteunt dit via SSL-proxy-configuratie waarbij certificaten worden gebruikt voor de backend-verbinding. Front Door gebruikt standaard HTTPS voor backend-verbindingen wanneer App Services HTTPS ondersteunen. Organisaties moeten ervoor zorgen dat alle SSL-certificaten geldig zijn, regelmatig worden vernieuwd, en worden beheerd via Azure Key Vault voor centrale controle en automatische rotatie.

Deployment van WAF-configuraties moet worden geïntegreerd in Infrastructure as Code (IaC) workflows om ervoor te zorgen dat configuraties version controlled, reproduceerbaar en auditbaar zijn. Bicep of ARM-templates moeten worden gebruikt om WAF-beleid, routingregels, backendpools en health probes te definiëren, zodat wijzigingen kunnen worden gereviewd, getest en gecontroleerd geïmplementeerd via CI/CD-pipelines. Voor wijzigingen aan WAF-configuraties moeten approval gates worden geconfigureerd die vereisen dat security officers of andere geautoriseerde personen expliciet goedkeuring geven voordat wijzigingen worden geïmplementeerd in productie-omgevingen. Dit voorkomt dat onbedoelde wijzigingen leiden tot beveiligingslekken of service-onderbrekingen. Canary deployments kunnen worden gebruikt om WAF-configuratiewijzigingen geleidelijk uit te rollen, waarbij eerst een klein percentage van het verkeer wordt gerouteerd naar een nieuwe WAF-configuratie terwijl de rest van het verkeer de bestaande configuratie gebruikt. Als er tijdens de canary-fase geen problemen worden gedetecteerd (zoals verhoogde blokkering van legitiem verkeer of performance-problemen), kan het percentage geleidelijk worden verhoogd totdat alle verkeer de nieuwe configuratie gebruikt. Deze aanpak minimaliseert het risico van configuratiefouten die grote impact hebben op gebruikers en maakt het mogelijk om snel terug te rollen wanneer problemen worden gedetecteerd. Monitoring moet tijdens canary deployments extra aandachtig zijn om snel te detecteren wanneer nieuwe configuraties problemen veroorzaken.

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 App Service: Web Application Firewall Configuratie .DESCRIPTION Controleert of Azure App Services zijn beschermd door Web Application Firewall via Azure Application Gateway WAF_v2 of Azure Front Door Premium WAF. Het script inventariseert: - App Services die direct via internet toegankelijk zijn - Application Gateway-configuraties met WAF-beleid - Front Door-configuraties met WAF-beleid - Integratie tussen WAF en App Services - WAF-beleidsconfiguraties en -status Dit script is bedoeld als ondersteunende monitoring voor het artikel 'Web Application Firewall Configuratie' en geeft security- en netwerkteams inzicht in waar WAF-bescherming ontbreekt of niet correct is geconfigureerd. Het script wijzigt zelf niets aan resources. .NOTES Filename: web-application-firewall.ps1 Author: Nederlandse Baseline voor Veilige Cloud Created: 2025-01-15 Last Modified: 2025-01-15 Version: 1.0 Related JSON: content/azure/app-service/web-application-firewall.json .PARAMETER WhatIf Toont wat het script zou doen zonder verbinding met Azure te maken. Handig voor lokale tests of om impact in te schatten. .PARAMETER Monitoring Voert de uitgebreide monitoringweergave uit met samenvatting en details. .EXAMPLE .\web-application-firewall.ps1 Voert een basiscontrole uit en retourneert een object met resultaten. .EXAMPLE .\web-application-firewall.ps1 -Monitoring Toont een leesbaar overzicht in de console. .EXAMPLE .\web-application-firewall.ps1 -WhatIf Voert alleen een dry-run uit zonder Azure-verbinding (voor snelle lokale test). #> # ============================================================================ # REQUIREMENTS # ============================================================================ #Requires -Version 5.1 #Requires -Modules Az.Accounts #Requires -Modules Az.Websites #Requires -Modules Az.Network # ============================================================================ # PARAMETERS # ============================================================================ [CmdletBinding()] param( [Parameter()][switch]$WhatIf, [Parameter()][switch]$Monitoring ) # ============================================================================ # GLOBAL SETTINGS # ============================================================================ $ErrorActionPreference = 'Stop' $VerbosePreference = 'SilentlyContinue' $PolicyName = "Azure App Service: Web Application Firewall Configuratie" # ============================================================================ # FUNCTION: Test-ModuleAvailability # ============================================================================ function Test-ModuleAvailability { <# .SYNOPSIS Controleert of vereiste Az-modules beschikbaar zijn. #> [CmdletBinding()] param() $requiredModules = @('Az.Accounts', 'Az.Websites', 'Az.Network') $missing = @() foreach ($m in $requiredModules) { if (-not (Get-Module -ListAvailable -Name $m)) { $missing += $m } } return $missing } # ============================================================================ # FUNCTION: Connect-IfNeeded # ============================================================================ function Connect-IfNeeded { <# .SYNOPSIS Maakt verbinding met Azure indien nog geen context actief is. #> [CmdletBinding()] param() if ($WhatIf) { Write-Verbose "WhatIf is ingeschakeld - geen Azure-verbinding maken." return } try { $context = Get-AzContext -ErrorAction SilentlyContinue if (-not $context) { Write-Host "Verbinding maken met Azure..." -ForegroundColor Yellow Connect-AzAccount -ErrorAction Stop | Out-Null $context = Get-AzContext Write-Host "Verbonden met Azure als $($context.Account.Id)" -ForegroundColor Green } else { Write-Verbose "Reeds verbonden met Azure als $($context.Account.Id)" } } catch { Write-Error "Kon niet verbinden met Azure: $_" throw } } # ============================================================================ # FUNCTION: Get-AppServiceWAFStatus # ============================================================================ function Get-AppServiceWAFStatus { <# .SYNOPSIS Analyseert WAF-bescherming voor een specifieke App Service. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [Microsoft.Azure.Commands.WebApps.Models.PSSite]$WebApp ) $info = [PSCustomObject]@{ Name = $WebApp.Name ResourceGroup = $WebApp.ResourceGroup Location = $WebApp.Location IsPublic = $true HasWAFProtection = $false WAFType = $null WAFPolicyName = $null WAFPolicyResourceGroup = $null IsProtectedByAppGateway = $false IsProtectedByFrontDoor = $false Issues = @() } try { $appService = Get-AzWebApp -ResourceGroupName $WebApp.ResourceGroup -Name $WebApp.Name -ErrorAction Stop # Controleren of App Service publiek toegankelijk is $siteConfig = Get-AzWebAppConfig -ResourceGroupName $WebApp.ResourceGroup -Name $WebApp.Name -ErrorAction SilentlyContinue if ($siteConfig) { # Controleren op IP-restrictions die publieke toegang beperken if ($siteConfig.IpSecurityRestrictions -and $siteConfig.IpSecurityRestrictions.Count -gt 0) { $hasPublicAccess = $false foreach ($restriction in $siteConfig.IpSecurityRestrictions) { if ($restriction.Action -eq 'Allow' -and (-not $restriction.IpAddress -or $restriction.IpAddress -eq 'Any')) { $hasPublicAccess = $true break } } $info.IsPublic = $hasPublicAccess } } # Controleren op Application Gateway WAF-bescherming try { $appGateways = Get-AzApplicationGateway -ErrorAction SilentlyContinue foreach ($gateway in $appGateways) { if ($gateway.WebApplicationFirewallConfiguration -and $gateway.WebApplicationFirewallConfiguration.Enabled) { # Controleren of deze App Service is geconfigureerd als backend in de gateway $backendPools = $gateway.BackendAddressPools foreach ($pool in $backendPools) { $backendAddresses = $pool.BackendAddresses if ($backendAddresses) { foreach ($address in $backendAddresses) { $fqdn = $address.Fqdn if ($fqdn -and ($fqdn -like "*$($appService.DefaultHostName)*" -or $fqdn -eq $appService.DefaultHostName)) { $info.HasWAFProtection = $true $info.WAFType = "Application Gateway" $info.IsProtectedByAppGateway = $true $info.WAFPolicyName = $gateway.WebApplicationFirewallConfiguration.FirewallPolicyId -split '/' | Select-Object -Last 1 break } } } } } if ($info.HasWAFProtection) { break } } } catch { Write-Verbose "Kon Application Gateway-configuraties niet controleren: $_" } # Controleren op Front Door WAF-bescherming if (-not $info.HasWAFProtection) { try { $frontDoors = Get-AzFrontDoor -ErrorAction SilentlyContinue foreach ($frontDoor in $frontDoors) { # Controleren of deze App Service is geconfigureerd als backend in Front Door $backends = $frontDoor.BackendPools if ($backends) { foreach ($backend in $backends) { $backendObjects = $backend.Backends if ($backendObjects) { foreach ($backendObj in $backendObjects) { $backendAddress = $backendObj.Address if ($backendAddress -and ($backendAddress -like "*$($appService.DefaultHostName)*" -or $backendAddress -eq $appService.DefaultHostName)) { # Controleren of Front Door WAF-policy heeft if ($frontDoor.FrontendEndpoints) { foreach ($endpoint in $frontDoor.FrontendEndpoints) { if ($endpoint.WebApplicationFirewallPolicyLink) { $info.HasWAFProtection = $true $info.WAFType = "Front Door" $info.IsProtectedByFrontDoor = $true $wafPolicyId = $endpoint.WebApplicationFirewallPolicyLink.Id $info.WAFPolicyName = $wafPolicyId -split '/' | Select-Object -Last 1 break } } } } if ($info.HasWAFProtection) { break } } } if ($info.HasWAFProtection) { break } } } if ($info.HasWAFProtection) { break } } } catch { Write-Verbose "Kon Front Door-configuraties niet controleren: $_" } } # Issues identificeren if ($info.IsPublic -and -not $info.HasWAFProtection) { $info.Issues += "Publiek toegankelijke App Service zonder WAF-bescherming" } if ($info.HasWAFProtection) { # Controleren of WAF-policy actief is try { if ($info.WAFType -eq "Application Gateway") { $wafPolicy = Get-AzApplicationGatewayFirewallPolicy -Name $info.WAFPolicyName -ResourceGroupName $info.ResourceGroup -ErrorAction SilentlyContinue if (-not $wafPolicy) { $info.Issues += "WAF-policy niet gevonden of niet toegankelijk" } } elseif ($info.WAFType -eq "Front Door") { $wafPolicy = Get-AzFrontDoorWafPolicy -Name $info.WAFPolicyName -ResourceGroupName $info.ResourceGroup -ErrorAction SilentlyContinue if (-not $wafPolicy) { $info.Issues += "WAF-policy niet gevonden of niet toegankelijk" } } } catch { Write-Verbose "Kon WAF-policy niet controleren: $_" } } } catch { Write-Verbose "Kon App Service-details niet ophalen voor $($WebApp.Name): $_" $info.Issues += "Kon configuratie niet volledig analyseren: $_" } return $info } # ============================================================================ # FUNCTION: Test-WAFConfiguration # ============================================================================ function Test-WAFConfiguration { <# .SYNOPSIS Voert controle uit op WAF-configuraties voor App Services. .OUTPUTS PSCustomObject met samenvatting en details. #> [CmdletBinding()] param() $result = [PSCustomObject]@{ ScriptName = "web-application-firewall" PolicyName = $PolicyName IsCompliant = $false TotalAppServices = 0 PublicAppServices = 0 ProtectedAppServices = 0 UnprotectedAppServices = 0 Details = @() UnprotectedServices = @() Recommendations = @() } $missingModules = Test-ModuleAvailability if ($missingModules.Count -gt 0) { $result.Details += "Vereiste Az-modules ontbreken: $($missingModules -join ', '). Installeer deze modules om de controle volledig uit te voeren." $result.IsCompliant = $false return $result } Connect-IfNeeded try { $webApps = Get-AzWebApp -ErrorAction SilentlyContinue if (-not $webApps) { $result.Details += "Geen App Services gevonden in de huidige context." $result.IsCompliant = $true return $result } $webApps = @($webApps) $result.TotalAppServices = $webApps.Count foreach ($app in $webApps) { Write-Verbose "Analyseren van App Service: $($app.Name)" $wafStatus = Get-AppServiceWAFStatus -WebApp $app if ($wafStatus.IsPublic) { $result.PublicAppServices++ if ($wafStatus.HasWAFProtection) { $result.ProtectedAppServices++ $result.Details += "✓ App Service '$($wafStatus.Name)' is beschermd door $($wafStatus.WAFType) WAF (Policy: $($wafStatus.WAFPolicyName))." } else { $result.UnprotectedAppServices++ $result.UnprotectedServices += $wafStatus $result.Details += "✗ App Service '$($wafStatus.Name)' is publiek toegankelijk maar niet beschermd door WAF (ResourceGroup: $($wafStatus.ResourceGroup))." } if ($wafStatus.Issues.Count -gt 0) { foreach ($issue in $wafStatus.Issues) { $result.Details += " ⚠ $issue" } } } else { $result.Details += "○ App Service '$($wafStatus.Name)' is niet publiek toegankelijk (private endpoint of IP-restrictions)." } } # Compliance bepalen if ($result.PublicAppServices -eq 0) { $result.IsCompliant = $true $result.Details += "Geen publiek toegankelijke App Services gevonden." } elseif ($result.UnprotectedAppServices -eq 0) { $result.IsCompliant = $true } else { $result.IsCompliant = $false } # Aanbevelingen if ($result.UnprotectedAppServices -gt 0) { $result.Recommendations += "Implementeer WAF-bescherming voor $($result.UnprotectedAppServices) publiek toegankelijke App Service(s) zonder WAF." $result.Recommendations += "Overweeg Azure Application Gateway WAF_v2 voor regionale scenario's of Azure Front Door Premium WAF voor globale diensten." } if ($result.ProtectedAppServices -gt 0) { $result.Recommendations += "Controleer regelmatig WAF-logs voor geblokkeerde aanvallen en pas WAF-beleid aan op basis van threat intelligence." } if ($result.PublicAppServices -gt 0) { $result.Recommendations += "Overweeg het gebruik van private endpoints voor App Services die niet direct via internet toegankelijk hoeven te zijn." } } catch { $result.Details += "Fout tijdens controle: $($_.Exception.Message)" Write-Error $_ } return $result } # ============================================================================ # FUNCTION: Invoke-Monitoring # ============================================================================ function Invoke-Monitoring { <# .SYNOPSIS Toont een leesbaar overzicht van de WAF-configuratiecontroles. #> [CmdletBinding()] param() Write-Host "`nWeb Application Firewall Monitoring" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "=======================================" -ForegroundColor Cyan $result = Test-WAFConfiguration Write-Host "`nSamenvatting:" -ForegroundColor Yellow Write-Host (" Totaal App Services : {0}" -f $result.TotalAppServices) -ForegroundColor Cyan Write-Host (" Publiek toegankelijk : {0}" -f $result.PublicAppServices) -ForegroundColor Cyan Write-Host (" Met WAF-bescherming : {0}" -f $result.ProtectedAppServices) -ForegroundColor Green Write-Host (" Zonder WAF-bescherming : {0}" -f $result.UnprotectedAppServices) -ForegroundColor (if ($result.UnprotectedAppServices -gt 0) { "Red" } else { "Green" }) if ($result.Details) { Write-Host "`nDetails:" -ForegroundColor Yellow foreach ($d in $result.Details) { $c = if ($d -like "✓*") { "Green" } elseif ($d -like "✗*") { "Red" } elseif ($d -like "⚠*") { "Yellow" } elseif ($d -like "○*") { "Gray" } else { "White" } Write-Host " $d" -ForegroundColor $c } } if ($result.Recommendations) { Write-Host "`nAanbevelingen:" -ForegroundColor Yellow foreach ($r in $result.Recommendations) { Write-Host " → $r" -ForegroundColor Cyan } } if ($result.IsCompliant) { Write-Host "`n✅ Alle publiek toegankelijke App Services zijn beschermd door WAF." -ForegroundColor Green } else { Write-Host "`n⚠️ Er zijn publiek toegankelijke App Services zonder WAF-bescherming. Zie aanbevelingen voor vervolgstappen." -ForegroundColor Yellow } return $result } # ============================================================================ # MAIN # ============================================================================ try { if ($PSBoundParameters.ContainsKey('WhatIf') -and $WhatIf) { Write-Host "`n=== WHATIF MODE ===" -ForegroundColor Yellow Write-Host "Het script zou de volgende controles uitvoeren:" -ForegroundColor Yellow Write-Host " - Verbinding maken met Azure (indien nog niet verbonden)" -ForegroundColor Yellow Write-Host " - Alle App Services inventariseren in de huidige context" -ForegroundColor Yellow Write-Host " - Controleren welke App Services publiek toegankelijk zijn" -ForegroundColor Yellow Write-Host " - Controleren op WAF-bescherming via Application Gateway of Front Door" -ForegroundColor Yellow Write-Host " - Rapporteren over App Services zonder WAF-bescherming" -ForegroundColor Yellow Write-Host "===================`n" -ForegroundColor Yellow return } if ($Monitoring) { Invoke-Monitoring | Out-Null } else { # Standaard: retourneer alleen het object, zonder uitgebreide console-output. Test-WAFConfiguration } } catch { Write-Error ("Er is een fout opgetreden in {0}: {1}" -f $PolicyName, $_) exit 1 }

Risico zonder implementatie

Risico zonder implementatie
Critical: Azure App Service-applicaties zonder WAF-bescherming zijn direct blootgesteld aan geautomatiseerde aanvallen, OWASP Top 10-exploits en volumetrische dreigingen zoals DDoS. Zonder WAF worden kwetsbaarheden direct geëxploiteerd voordat patches kunnen worden geïmplementeerd, wat leidt tot datalekken, service-onderbrekingen en compliance-schendingen. Het ontbreken van WAF-bescherming schendt BIO-controles voor applicatiebeveiliging en ISO 27001-vereisten voor defense-in-depth, wat kan resulteren in auditbevindingen, certificeringsproblemen en bestuurlijke aansprakelijkheid. Voor internetgerichte App Services die persoonsgegevens verwerken of kritieke diensten leveren, is het risico kritiek.

Management Samenvatting

Web Application Firewall voor Azure App Service biedt essentiële bescherming tegen OWASP Top 10-aanvallen, geautomatiseerde exploits en volumetrische dreigingen door verkeer te filteren voordat het de applicatie bereikt. Implementatie omvat keuze tussen Application Gateway WAF_v2 (regionaal) of Front Door Premium WAF (globaal), configuratie van OWASP-regelsets en custom regels, gefaseerde activering via detectie- en preventiemodi, en uitgebreide monitoring en logging voor security operations en compliance. De implementatie vergt circa 24 uur (16 uur technisch, 8 uur organisatorisch) maar levert kritieke risicoreductie op en voldoet aan BIO, ISO 27001 en NIS2-vereisten voor defense-in-depth-beveiliging. Maandelijkse kosten variëren van €200-500 per WAF-instance afhankelijk van gekozen oplossing en verkeersvolumes.