SurePassID MFA Server

Hardened web.config Guide

This document describes a security-hardened review copy of the application web.config. It explains every hardening change (the H# markers) and documents what each affected parameter means.

How to use this file: Review each change below in a staging environment, migrate the secrets to encrypted configuration or Azure Key Vault, then rename web.config.hardened to web.config.


Summary of hardening changes

ID Area Change
H1 Secrets Secrets removed from clear text (DB password, SMTP password, System.Key/IV/Salt). Store encrypted or in Key Vault.
H2 Tracing Server.Trace disabled and trace path moved off C:\temp.
H3 Compilation compilation debug="false" and targetFramework corrected to 4.8.
H4 Errors customErrors mode="RemoteOnly" with a defaultRedirect (no stack traces to clients).
H5 HTTP runtime Version header off, request size/URL limits, request validation.
H6 Cookies Secure cookies (HttpOnly, requireSSL, SameSite).
H7 Session sessionState hardened (cookie only, SSL, SameSite, regenerate expired id).
H8 IIS errors httpErrors set to DetailedLocalOnly; ASP script errors not sent to browser.
H9 Headers Security response headers added; Server / X-Powered-By / version headers removed.
H10 Modules runAllManagedModulesForAllRequests set to false.
H11 Diagnostics Trace switch lowered from All to Warning.

H1 — Remove secrets from clear text

Cryptographic material and credentials must never be committed in clear text. All exposed values should be rotated and stored encrypted (via aspnet_regiis / DPAPI / PKCS12) or in Azure Key Vault. See WebConfig-Encryption-Guide` for the full encryption workflow.

Affected settings (placeholder values indicate the secret must be supplied securely):

Setting Meaning
Connection.Password SQL Server authentication password. Prefer Windows/Integrated auth (managed service account); otherwise store encrypted. Set to __SET_VIA_ENCRYPTED_CONFIG_OR_KEYVAULT__.
System.Key Symmetric key for the SurePass local key provider. Must be rotated and encrypted.
System.IV Initialization vector paired with System.Key.
System.Salt Salt used in key derivation.
system.net/mailSettings/smtp password SMTP account password for outbound mail. Encrypt this section or store securely.
IGNORE.Saml.PersistentNameIdSalt Salt for persistent SAML NameID generation. Use a strong, unique value (not the sample your-secret-salt); store encrypted.
Pkcs11.Pin (HSM, optional) PKCS#11 token PIN. Supply via encrypted config, never clear text.
Eam.ClientSecret (optional) Defense-in-depth shared secret for EAM. Store encrypted if used.

configProtectedData provider (commented template)

A Pkcs12Provider block is included (commented) so appSettings and the SMTP section can be encrypted using a certificate. PKCS12 works for both single servers and server farms; DPAPI (DataProtectionConfigurationProvider) is single-server only. Azure-hosted deployments should use the existing Azure Key Vault path.


H2 — Disable production tracing

Setting Value Meaning
Server.Trace 0 Disables verbose server tracing. Enable only for short-term troubleshooting.
Server.TracePath D:\Logs\SurePassIdp Moves trace output off C:\temp to a restricted, app-writable log directory.
Saml2.TraceSensitiveData false Prevents diagnostic logs from leaking tokens/PII. Keep false in production.

H3 — Compilation settings

<compilation debug="false" targetFramework="4.8" />
  • debug="false" — Required in production. Disables debug binaries, prevents detailed compiler-generated diagnostics, and improves performance.
  • targetFramework="4.8" — Corrected to the actual target framework so runtime behavior/quirks match .NET Framework 4.8.

H4 — Custom errors

<customErrors mode="RemoteOnly" defaultRedirect="~/Error.aspx" />
  • mode="RemoteOnly" — Detailed error pages are shown only to local (server) requests; remote clients never see stack traces.
  • defaultRedirect="~/Error.aspx" — Generic error page shown to clients. Provide an Error.aspx.

H5 — httpRuntime hardening

<httpRuntime enableVersionHeader="false"
             targetFramework="4.8"
             maxRequestLength="4096"
             requestValidationMode="4.5"
             maxUrlLength="2048"
             maxQueryStringLength="2048" />
Attribute Meaning
enableVersionHeader="false" Removes the X-AspNet-Version disclosure header.
targetFramework="4.8" Ensures ASP.NET runtime behaviors align with 4.8.
maxRequestLength="4096" Maximum request body size in KB (4 MB). Limits large-upload abuse.
requestValidationMode="4.5" Enables ASP.NET request validation (helps mitigate XSS-style input).
maxUrlLength="2048" Maximum URL length in characters.
maxQueryStringLength="2048" Maximum query string length in characters.

H6 — Secure cookies

<httpCookies httpOnlyCookies="true" requireSSL="true" sameSite="Strict" />
Attribute Meaning
httpOnlyCookies="true" Cookies are inaccessible to client-side script (mitigates XSS token theft).
requireSSL="true" Cookies are sent only over HTTPS.
sameSite="Strict" Cookies are not sent on cross-site requests (mitigates CSRF).

H7 — Session state hardening

<sessionState mode="InProc"
              timeout="20"
              cookieless="UseCookies"
              cookieSameSite="Strict"
              regenerateExpiredSessionId="true" />
Attribute Meaning
mode="InProc" Session stored in-process.
timeout="20" Idle session lifetime in minutes.
cookieless="UseCookies" Session ID carried in a cookie, never in the URL.
cookieSameSite="Strict" Session cookie not sent cross-site.
regenerateExpiredSessionId="true" Issues a new session ID when an expired one is presented (mitigates session fixation).

Related commented guidance is included for enforcing requireSSL on Forms auth and for defining an explicit machineKey in web-farm scenarios.


H8 — IIS error handling

<httpErrors errorMode="DetailedLocalOnly" existingResponse="Auto" />
<asp scriptErrorSentToBrowser="false" />
  • errorMode="DetailedLocalOnly" — Detailed IIS errors only for local requests; remote clients get generic errors.
  • existingResponse="Auto" — Lets the app-provided error response pass through when present.
  • scriptErrorSentToBrowser="false" — Classic ASP script errors are not leaked to the browser.

H9 — Security response headers

<security>
  <requestFiltering removeServerHeader="true">
    <requestLimits maxAllowedContentLength="4194304" />
  </requestFiltering>
</security>

<httpProtocol>
  <customHeaders>
    <remove name="X-Powered-By" />
    <add name="X-Content-Type-Options" value="nosniff" />
    <add name="X-Frame-Options" value="SAMEORIGIN" />
    <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
    <add name="X-XSS-Protection" value="0" />
    <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
  </customHeaders>
</httpProtocol>
Header / setting Meaning
removeServerHeader="true" Removes the IIS Server disclosure header.
maxAllowedContentLength="4194304" Maximum request content length in bytes (4 MB) at the IIS layer.
remove X-Powered-By Removes the ASP.NET disclosure header.
X-Content-Type-Options: nosniff Prevents MIME-type sniffing.
X-Frame-Options: SAMEORIGIN Prevents clickjacking by disallowing cross-origin framing.
Referrer-Policy: strict-origin-when-cross-origin Limits referrer information sent cross-origin.
X-XSS-Protection: 0 Explicitly disables the legacy XSS auditor (deprecated; 0 is the recommended value).
Strict-Transport-Security: max-age=31536000; includeSubDomains Forces HTTPS for one year across subdomains (HSTS).

A Content-Security-Policy header is provided but commented out; tune it to the app's assets before enabling site-wide. The defaultDocument list is also trimmed to remove unused default files.


H10 — Managed modules

<modules runAllManagedModulesForAllRequests="false">
  • runAllManagedModulesForAllRequests="false" — Managed modules do not run for every request (including static files), reducing attack surface and improving performance.

H11 — Diagnostics trace switch

<source name="SSOTrace" switchValue="Warning">
  • switchValue="Warning" — Lowered from All so only warnings and errors are logged, reducing the volume of potentially sensitive diagnostic output.

Non-hardening settings (unchanged, for reference)

These application settings are not part of the hardening changes but appear in the file:

  • Connection. Connection.ConnectionType, Connection.Database, Connection.Server, Connection.Username, Connection.Options (now includes Encrypt=True;TrustServerCertificate=False for TLS to SQL), Connection.AuthenticationMethod (0=SQL auth, 1=Windows auth, recommended).
  • System key management. System.KeyType, System.KeyEndPoint (plus optional Pkcs11.* HSM block).
  • Support/Server/Authorization. Help site, product/company names, Server.AppId, push endpoints, Authorization.ServerURL, System.Login2FAMethods.
  • FIDO. FIDO.PasswordlessEnabled, FIDO.SecondFactorEnabled.
  • EAM (Entra External Authentication Method). Eam.* client, redirect, ACR, and discovery settings. Production redirect/discovery URLs should use HTTPS, not http/localhost.
  • Caching. SamlCache.Provider (InMemory or SqlServer), SamlCache.RequestIdExpirationMinutes, SamlCache.SessionExpirationHours. See Documentation/Setup/SAML2-WebConfig-Settings-And-Caching.md.

Deployment checklist

  1. Rotate every exposed secret (DB, SMTP, System.Key/IV/Salt, NameID salt).
  2. Encrypt appSettings and system.net/mailSettings/smtp per WebConfig-Encryption-Guide.md, or move secrets to Key Vault.
  3. Ensure the trace/log directory (Server.TracePath) exists and is writable only by the app pool identity.
  4. Provide Error.aspx for customErrors.
  5. Grant the app pool identity Read on the PKCS12 certificate private key (if used).
  6. Validate in staging, then rename web.config.hardened to web.config.
SurePassID 360 Central Avenue #800 St. Petersburg, FL 33701 USA +1 (888) 200-8144 surepassid.com