In einem IIS mit ARR der andere Web-Services hinter sich schützt, tritt (gehäuft in letzter Zeit) schon mal ein „unerwarteter“ Fehler 400 auf. Im Ereignisprotokoll gibt es auch einen (ernsthaft) hilfreichen Hinweis. Der Fehler tritt gehäuft bei Sites auf, die das Angular Framework verwenden.
Eventlog Anwendung, Quelle ASP.NET 4.0.<build>, Ereignis-ID (EventID) 1309,
Event code: 3005
Event message: Es ist eine unbehandelte Ausnahme aufgetreten.
Application information:
Trust level: Full
Application Virtual Path: /
Application Path: C:\inetpub\<PATH>
Exception information:
Exception type: HttpException
Exception message: Ein möglicherweise gefährlicher Request.Path-Wert wurde vom Client (:) entdeckt.
bei System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
bei System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
Die Request URL enthält einen Doppelpunkt. Einen „gefährlichen“ Doppelpunkt!!1elf
Dass der Doppelpunkt „gefährlich“ ist, liegt grundsätzlich nicht am IIS, sondern an der RFC1738, die genau definiert, wie eine URL aussehen darf („Uniform Resource Locators“). Darin ist nämlich festgelegt, dass …
„…only alphanumerics, the special characters „$-_.+!‘(), and reserved characters used for their *reserved purposes* may be used unencoded within a URL„
Der Doppelpunkt („colon“) „:“ ist so ein reserviertes Zeichen. Die RFC wird sogar noch deutlicher: „it’s used after the protocol (http, https) and after the domain to specify a port.“
Natürlich lässt sich das Verhalten des IIS anpassen, um solche „illegalen“ Requests zu erlauben. Das sollte man aber zumindest mit seinen Security-Leuten absprechen, die Änderung ist nicht ganz ohne. Die „Lösung“ hier lädt nur die Waffe, wenn sich der Admin damit selber ins Knie schießt, ist das sein Problem 😉
Lösung
Die „richtige“ Lösung ist natürlich, in der Webseite (Web App, Service, was auch immer) korrekt zu serialisieren. Angular nutzt dazu den UrlSerializer router; richtig eingesetzt tritt der Fehler nicht auf.
Oft hat man als Admin „am anderen Ende“ aber keinen Einfluss auf die Entwicklung so einer App. Man kann daher in der Site-Konfiguration (web.config) auf dem IIS die Request-Filterung konfigurieren.
Das hier ist eine Beispiel-Konfiguration, die mehrere solcher „Eigenheiten“ umgeht.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<!-- Off=Debugausgaben in HTTP-Fehlern
On=Gekuerzte Ausgavben (Produktivumgebung)
-->
<customErrors mode="Off" />
<!--
maxUrlLength: Lange Request URIs erlauben
maxQueryStringLength: Lange Query-String (nach dem '?') erlauben
relaxedUrlToFileSystemMapping: Dateisystemspfade (Doppelpunkte, \\?\) in URIs erlauben
requestPathInvalidCharacters: Bestimmte Zeichen erlauben
-->
<httpRuntime
maxUrlLength="10999"
maxQueryStringLength="2097151"
relaxedUrlToFileSystemMapping="true"
requestPathInvalidCharacters="*,%,?,\,&,<,>"
/>
</system.web>
<system.webServer>
<security>
<!-- allowDoubleEscaping: \\ vor ? erlauben
-->
<requestFiltering allowDoubleEscaping="true">
<requestLimits maxUrl="10999" maxQueryString="2097151" />
</requestFiltering>
</security>