Security problem of mapping file structure of Azure Web App and other IIS APP – part 1.

If you deploy sample ASP.NET 4.x pure, out of the box web app (https://portal.azure.com/#create/Microsoft.WebSite) the behaviors is like:

https://pure.azurewebsites.net/yfgrueygfuyrgfrf – 404 error – what is ok…

https://pure.azurewebsites.net/a/a.txt – 200 OK (of course you need first put a.txt file to this directory)

https://pure.azurewebsites.net/a/ – 403 forbidden – so it means that hacker can search for something here. Expected secure behavior is to return here 404 also…

 

I tried to test UMBRACO CMS deployed from Azure marketplace (https://portal.azure.com/#create/umbracoorg.UmbracoCMS) what seems to be written to avoid mapping file structure – just see:

https://umbrecomf.azurewebsites.net/wruihfgweihgufr – 404 error

https://umbrecomf.azurewebsites.net/a/a.txt – 200 – OK (of course you need first put a.txt file to this directory)

https://umbrecomf.azurewebsites.net/a/ – Also 404…  – What is OK…. We need this behavior…

This behavior is because the UMBRACO CMS is routing all requests into the Umbraco app (<modules runAllManagedModulesForAllRequests=”true”>)  – and when the CMS encounters a path that hasn’t been configured in their system, it returns a 404. So it is addressed programmatically.

UMBRACO CMS web.config:

<?xml version=”1.0″ encoding=”utf-8″?>

<configuration>

<!–

Define the Web.config template, which is used when creating the initial Web.config,

and then transforms from web.Template.[Debug|Release].config are applied.

Documentation for Web.config at: https://our.umbraco.com/documentation/Reference/Config/webconfig/

–>

 

<configSections>

<section name=”clientDependency” type=”ClientDependency.Core.Config.ClientDependencySection, ClientDependency.Core” requirePermission=”false” />

 

<sectionGroup name=”umbracoConfiguration”>

<section name=”settings” type=”Umbraco.Core.Configuration.UmbracoSettings.UmbracoSettingsSection, Umbraco.Core” requirePermission=”false” />

<section name=”HealthChecks” type=”Umbraco.Core.Configuration.HealthChecks.HealthChecksSection, Umbraco.Core” requirePermission=”false” />

</sectionGroup>

 

<sectionGroup name=”imageProcessor”>

<section name=”security” requirePermission=”false” type=”ImageProcessor.Web.Configuration.ImageSecuritySection, ImageProcessor.Web” />

<section name=”processing” requirePermission=”false” type=”ImageProcessor.Web.Configuration.ImageProcessingSection, ImageProcessor.Web” />

<section name=”caching” requirePermission=”false” type=”ImageProcessor.Web.Configuration.ImageCacheSection, ImageProcessor.Web” />

</sectionGroup>

</configSections>

 

<umbracoConfiguration>

<settings configSource=”config\umbracoSettings.config” />

<HealthChecks configSource=”config\HealthChecks.config” />

</umbracoConfiguration>

 

<clientDependency configSource=”config\ClientDependency.config” />

 

<appSettings>

<add key=”Umbraco.Core.ConfigurationStatus” value=”8.13.0″ />

<add key=”Umbraco.Core.ReservedUrls” value=”” />

<add key=”Umbraco.Core.ReservedPaths” value=”” />

<add key=”Umbraco.Core.Path” value=”~/umbraco” />

<add key=”Umbraco.Core.HideTopLevelNodeFromPath” value=”true” />

<add key=”Umbraco.Core.TimeOutInMinutes” value=”20″ />

<add key=”Umbraco.Core.DefaultUILanguage” value=”en-US” />

<add key=”Umbraco.Core.UseHttps” value=”false” />

<add key=”Umbraco.Core.AllowContentDashboardAccessToAllUsers” value=”true” />

 

<add key=”ValidationSettings:UnobtrusiveValidationMode” value=”None” />

<add key=”webpages:Enabled” value=”false” />

<add key=”enableSimpleMembership” value=”false” />

<add key=”autoFormsAuthentication” value=”false” />

<add key=”dataAnnotations:dataTypeAttribute:disableRegEx” value=”false” />

 

<add key=”owin:appStartup” value=”UmbracoDefaultOwinStartup” />

 

<add key=”Umbraco.ModelsBuilder.Enable” value=”true” />

<add key=”Umbraco.ModelsBuilder.ModelsMode” value=”PureLive” />

</appSettings>

 

<!–

Important: if you’re upgrading Umbraco, do not clear the connectionString/providerName during your Web.config merge.

–>

<connectionStrings>

<remove name=”umbracoDbDSN” />

<add name=”umbracoDbDSN” connectionString=”Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;” providerName=”System.Data.SqlServerCe.4.0″ />

</connectionStrings>

 

<system.data>

<DbProviderFactories>

<remove invariant=”System.Data.SqlServerCe.4.0″ />

<add name=”Microsoft SQL Server Compact Data Provider 4.0″ invariant=”System.Data.SqlServerCe.4.0″ description=”.NET Framework Data Provider for Microsoft SQL Server Compact” type=”System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe” />

</DbProviderFactories>

</system.data>

 

<system.net>

<mailSettings>

<!–

If you need Umbraco to send out system mails (like reset password and invite user),

you must configure your SMTP settings here – for example:

–>

<!–

<smtp from=”noreply@example.com” deliveryMethod=”Network”>

<network host=”localhost” port=”25″ enableSsl=”false” userName=”” password=”” />

</smtp>

–>

</mailSettings>

</system.net>

 

<system.web>

<customErrors mode=”RemoteOnly” />

 

<trace enabled=”false” requestLimit=”10″ pageOutput=”false” traceMode=”SortByTime” localOnly=”true” />

 

<httpRuntime requestValidationMode=”2.0″ enableVersionHeader=”false” targetFramework=”4.7.2″ maxRequestLength=”51200″ fcnMode=”Single” />

 

<httpModules>

<add name=”ScriptModule” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ />

<add name=”UmbracoModule” type=”Umbraco.Web.UmbracoModule,Umbraco.Web” />

<add name=”ClientDependencyModule” type=”ClientDependency.Core.Module.ClientDependencyModule, ClientDependency.Core” />

<add name=”ImageProcessorModule” type=”ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web” />

</httpModules>

 

<httpHandlers>

<remove verb=”*” path=”*.asmx” />

<add verb=”*” path=”*.asmx” type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ validate=”false” />

<add verb=”*” path=”*_AppService.axd” type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ validate=”false” />

<add verb=”GET,HEAD” path=”ScriptResource.axd” type=”System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ validate=”false” />

<add verb=”*” path=”DependencyHandler.axd” type=”ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core ” />

</httpHandlers>

 

<compilation defaultLanguage=”c#” debug=”false” batch=”true” targetFramework=”4.7.2″ numRecompilesBeforeAppRestart=”50″ />

 

<authentication mode=”Forms”>

<forms name=”yourAuthCookie” loginUrl=”login.aspx” protection=”All” path=”/” />

</authentication>

 

<authorization>

<allow users=”?” />

</authorization>

 

<!– Membership Provider –>

<membership defaultProvider=”UmbracoMembershipProvider” userIsOnlineTimeWindow=”15″>

<providers>

<clear />

<add name=”UmbracoMembershipProvider” type=”Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco.Web” minRequiredNonalphanumericCharacters=”0″ minRequiredPasswordLength=”10″ useLegacyEncoding=”false” enablePasswordRetrieval=”false” enablePasswordReset=”false” requiresQuestionAndAnswer=”false” defaultMemberTypeAlias=”Member” passwordFormat=”Hashed” allowManuallyChangingPassword=”false” />

<add name=”UsersMembershipProvider” type=”Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco.Web” />

</providers>

</membership>

 

<!– Role Provider –>

<roleManager enabled=”true” defaultProvider=”UmbracoRoleProvider”>

<providers>

<clear />

<add name=”UmbracoRoleProvider” type=”Umbraco.Web.Security.Providers.MembersRoleProvider” />

</providers>

</roleManager>

 

</system.web>

 

<system.webServer>

<validation validateIntegratedModeConfiguration=”false” />

 

<modules runAllManagedModulesForAllRequests=”true”>

<remove name=”WebDAVModule” />

<remove name=”UmbracoModule” />

<remove name=”ScriptModule” />

<remove name=”ClientDependencyModule” />

<remove name=”FormsAuthentication” />

<remove name=”ImageProcessorModule” />

 

<add name=”UmbracoModule” type=”Umbraco.Web.UmbracoModule,Umbraco.Web” />

<add name=”ScriptModule” preCondition=”managedHandler” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ />

<add name=”ClientDependencyModule” type=”ClientDependency.Core.Module.ClientDependencyModule, ClientDependency.Core” />

<!– FormsAuthentication is needed for login/membership to work on homepage (as per http://stackoverflow.com/questions/218057/httpcontext-current-session-is-null-when-routing-requests) –>

<add name=”FormsAuthentication” type=”System.Web.Security.FormsAuthenticationModule” />

<add name=”ImageProcessorModule” type=”ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web” />

</modules>

 

<handlers accessPolicy=”Read, Write, Script, Execute”>

<remove name=”WebServiceHandlerFactory-Integrated” />

<remove name=”ScriptHandlerFactory” />

<remove name=”ScriptHandlerFactoryAppServices” />

<remove name=”ScriptResource” />

<remove name=”ClientDependency” />

<remove name=”MiniProfiler” />

<remove name=”ExtensionlessUrlHandler-Integrated-4.0″ />

<remove name=”OPTIONSVerbHandler” />

<remove name=”TRACEVerbHandler” />

 

<add name=”ScriptHandlerFactory” verb=”*” path=”*.asmx” preCondition=”integratedMode” type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ />

<add name=”ScriptHandlerFactoryAppServices” verb=”*” path=”*_AppService.axd” preCondition=”integratedMode” type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ />

<add name=”ScriptResource” verb=”GET,HEAD” path=”ScriptResource.axd” preCondition=”integratedMode” type=”System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ />

<add verb=”*” name=”ClientDependency” preCondition=”integratedMode” path=”DependencyHandler.axd” type=”ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core” />

<add name=”MiniProfiler” path=”mini-profiler-resources/*” verb=”*” type=”System.Web.Routing.UrlRoutingModule” resourceType=”Unspecified” preCondition=”integratedMode” />

<add name=”ExtensionlessUrlHandler-Integrated-4.0″ path=”*.” verb=”*” type=”System.Web.Handlers.TransferRequestHandler” preCondition=”integratedMode,runtimeVersionv4.0″ />

</handlers>

 

<staticContent>

<remove fileExtension=”.air” />

<mimeMap fileExtension=”.air” mimeType=”application/vnd.adobe.air-application-installer-package+zip” />

<remove fileExtension=”.svg” />

<mimeMap fileExtension=”.svg” mimeType=”image/svg+xml” />

<remove fileExtension=”.woff” />

<mimeMap fileExtension=”.woff” mimeType=”font/woff” />

<remove fileExtension=”.woff2″ />

<mimeMap fileExtension=”.woff2″ mimeType=”font/woff2″ />

<remove fileExtension=”.less” />

<mimeMap fileExtension=”.less” mimeType=”text/css” />

<remove fileExtension=”.mp4″ />

<mimeMap fileExtension=”.mp4″ mimeType=”video/mp4″ />

<remove fileExtension=”.json” />

<mimeMap fileExtension=”.json” mimeType=”application/json” />

</staticContent>

 

<!– Ensure the powered by header is not returned –>

<httpProtocol>

<customHeaders>

<remove name=”X-Powered-By” />

</customHeaders>

</httpProtocol>

 

<!– Increase the default upload file size limit –>

<security>

<requestFiltering>

<requestLimits maxAllowedContentLength=”52428800″ />

</requestFiltering>

</security>

 

<!–

If you wish to use IIS rewrite rules, see the documentation here: https://our.umbraco.com/documentation/Reference/Routing/IISRewriteRules

–>

<!–

<rewrite>

<rules></rules>

</rewrite>

–>

</system.webServer>

 

<runtime>

<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>

<dependentAssembly>

<assemblyIdentity name=”Microsoft.Owin” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-4.0.1.0″ newVersion=”4.0.1.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”Microsoft.Owin.Security” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-4.0.1.0″ newVersion=”4.0.1.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”Microsoft.Owin.Security.Cookies” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-4.0.1.0″ newVersion=”4.0.1.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”Microsoft.Owin.Security.OAuth” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-4.0.1.0″ newVersion=”4.0.1.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”Newtonsoft.Json” publicKeyToken=”30ad4fe6b2a6aeed” culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-12.0.0.0″ newVersion=”12.0.0.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”System.Collections.Immutable” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-1.2.3.0″ newVersion=”1.2.3.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”System.Web.Http” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-5.2.7.0″ newVersion=”5.2.7.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”System.Web.Mvc” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-5.2.7.0″ newVersion=”5.2.7.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”System.ValueTuple” publicKeyToken=”cc7b13ffcd2ddd51″ culture=”neutral” />

<bindingRedirect oldVersion=”0.0.0.0-4.0.3.0″ newVersion=”4.0.3.0″ />

</dependentAssembly>

<dependentAssembly>

<assemblyIdentity name=”System.Net.Http.Formatting” publicKeyToken=”31bf3856ad364e35″ />

<bindingRedirect oldVersion=”0.0.0.0-5.2.7.0″ newVersion=”5.2.7.0″ />

</dependentAssembly>

</assemblyBinding>

</runtime>

 

<location path=”umbraco”>

<system.webServer>

<urlCompression doStaticCompression=”false” doDynamicCompression=”false” dynamicCompressionBeforeCache=”false” />

</system.webServer>

</location>

<location path=”App_Plugins”>

<system.webServer>

<urlCompression doStaticCompression=”false” doDynamicCompression=”false” dynamicCompressionBeforeCache=”false” />

</system.webServer>

</location>

 

<imageProcessor>

<security configSource=”config\imageprocessor\security.config” />

<caching configSource=”config\imageprocessor\cache.config” />

<processing configSource=”config\imageprocessor\processing.config” />

</imageProcessor>

 

<system.codedom>

<compilers>

<compiler language=”c#;cs;csharp” extension=”.cs” type=”Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ warningLevel=”4″ compilerOptions=”/langversion:7 /nowarn:1659;1699;1701″ />

<compiler language=”vb;vbs;visualbasic;vbscript” extension=”.vb” type=”Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ warningLevel=”4″ compilerOptions=”/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+” />

</compilers>

</system.codedom>

 

</configuration>