On a multi-tenant Windows host, web.config is both a convenience and a blast radius. A single unlocked section can re-enable verbs you filtered, swap authentication modes, or load modules the app pool identity should never control. Feature Delegation is the IIS control plane that decides which system.webServer (and related) sections a site may override.

If you only harden requestFiltering and TLS at the server level, but leave delegation wide open, customers—or a compromised publish—can walk those settings back in applicationHost.config’s shadow: the site’s web.config. Lock the dangerous sections once, document the few you intentionally unlock, and verify with PowerShell after every role or cumulative update.

#What Feature Delegation actually controls

IIS reads effective configuration from machine.config, root web.config, applicationHost.config, then the site and app web.config files. Feature Delegation sets the overrideModeDefault (and per-location locks) for configuration sections. Read Only means site web.config cannot change that section. Read/Write allows override. Not Delegated hides the feature from IIS Manager at the site level and blocks overrides.

This is separate from NTFS ACLs and app pool identity. You still need least-privilege identities and a tight applicationHost.config; delegation is the config-schema gate so ASP.NET and ASP.NET Core apps cannot redefine server policy mid-request pipeline.

#Sections worth locking on .NET hosts

Start from a deny-by-default mindset for security and pipeline sections, then unlock only what your control panel or support process truly needs. On IIS 10.0 under Windows Server 2025, these are the usual high-value locks for shared and reseller Windows plans running .NET Framework and ASP.NET Core (ANCM):

  • system.webServer/security/* — requestFiltering, authentication, authorization, ipSecurity, isapiCgiRestriction
  • system.webServer/modules and handlers — prevents arbitrary native/managed module injection at site scope
  • system.webServer/proxy (if ARR is installed) — stops open-proxy style overrides
  • system.webServer/httpProtocol and rewrite (lock rules you manage centrally; unlock only if customers own their rewrite maps)
  • system.applicationHost/applicationPools equivalents are not site-delegated—keep pool settings out of customer reach via isolation and permissions

ASP.NET Core apps still ship a web.config that configures the AspNetCoreModuleV2 handler and environment variables. That handler entry must remain allowed at the app level, but customers should not be free to replace the global modules list or weaken requestFiltering. In-process and out-of-process hosting both honor server-level locks on security sections.

#Set locks with PowerShell (and verify)

IIS Manager’s Feature Delegation UI is fine for a one-off lab box. On real hosts, script the desired state so rebuilds and golden images stay honest. WebAdministration locks section override mode at the applicationHost level:

powershell
Import-Module WebAdministration

# Lock high-risk sections (Read Only at site level)
$lock = @(
  'system.webServer/security/requestFiltering',
  'system.webServer/security/authentication/anonymousAuthentication',
  'system.webServer/security/authentication/windowsAuthentication',
  'system.webServer/modules'
)

foreach ($section in $lock) {
  Set-WebConfiguration -Metadata overrideMode -Value Deny -Filter $section -PSPath 'MACHINE/WEBROOT/APPHOST'
}

# Allow ASP.NET Core / app-owned handler tweaks if your product requires it
Set-WebConfiguration -Metadata overrideMode -Value Allow `
  -Filter 'system.webServer/handlers' -PSPath 'MACHINE/WEBROOT/APPHOST'

# Quick audit: show overrideMode for security group
Get-WebConfiguration -Metadata overrideMode `
  -Filter 'system.webServer/security/*' -PSPath 'MACHINE/WEBROOT/APPHOST' |
  Select-Object SectionPath, EffectiveValue, IsLocked

After locking, drop a temporary web.config under a test site that tries to widen requestFiltering (for example, allowing high-bit characters or unlisted file extensions you blocked server-wide). Recycle the pool and confirm IIS returns a configuration error rather than silently accepting the override. Failed Request Tracing or the event log will show config file hierarchy failures when a locked section is touched.

#Operational notes for Server 2025 hosts

Cumulative updates and IIS feature installs can reset delegation for newly added sections. Fold a delegation audit into your patch window next to Schannel and .NET servicing checks. If you use shared configuration across a farm, set locks on the central applicationHost.config store and replicate; do not assume each node’s local UI state is authoritative.

Remote Management (WMSVC) users who connect as site-only operators only see features you delegated. That is useful, but it is not a substitute for locking: a full publish via Web Deploy can still push web.config. Pair Feature Delegation with requestFiltering, separate app pools per site, and denied write access to anything outside the site root.

For .NET Framework apps under Full Trust, config locks remain one of the few hard server-side brakes on pipeline tampering. For ASP.NET Core 10 on the ANCM module, treat web.config as deployment surface area: allow the handler and aspNetCore section patterns you support, and keep security/* read-only so environment-specific publish profiles cannot weaken the edge.

Practical takeaway: pick a short allowlist of delegable sections, encode it in PowerShell beside your IIS role build, and run the overrideMode audit after every Windows Server 2025 patch cycle. When a customer needs a one-off unlock, grant it on a location path for that site only, ticket it, and expire it—never flip the global default to Read/Write for convenience.