IIS: How to disable HTTP method TRACE? - http

I followed this, which led to this to try to disable my website from accepting the TRACE method (verb). Basically I added the section below to <system.webServer> inside Web.config (Default Web Site and the other website):
<security>
<requestFiltering>
<verbs applyToWebDAV="false">
<add verb="TRACE" allowed="false" />
</verbs>
</requestFiltering>
</security>
It didnĀ“t work. Then I went to C:\Windows\System32\inetsrv\config\applicationHost.config and replaced all handlers' verb inside <handlers>. In a nutshell, all lines like this:
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
Became this:
<add name="StaticFile" path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
I even restarted the server but when I check the available methods, TRACE is still there:
$ curl -I -X OPTIONS https://example.com/mysite
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Public: OPTIONS, TRACE, GET, HEAD, POST
X-XSS-Protection: 1; mode=block
Date: Thu, 07 Feb 2019 21:03:49 GMT
Content-Length: 0
So, how do I get rid of it?

To truly block TRACE requests, you should still keep a request filtering rule with TRACE verb blocked.
The curl command sends an OPTIONS request to IIS, and the ProtocolSupportModule generates the response message,
https://learn.microsoft.com/en-us/iis/get-started/introduction-to-iis/iis-modules-overview
However, Microsoft did not design any settings in system.webServer/httpProtocol section for you to change the value of the headers so as to hide TRACE from there.
But a workaround is to use URL Rewrite module,
https://blogs.msdn.microsoft.com/benjaminperkins/2012/11/02/change-or-modify-a-response-header-value-using-url-rewrite/
where you create two outbound rules for Allow and Public headers,
<rewrite>
<outboundRules>
<rule name="ChangeHeaders" stopProcessing="false">
<match serverVariable="RESPONSE_Allow" pattern="OPTIONS, TRACE, GET, HEAD, POST" />
<action type="Rewrite" value="OPTIONS, GET, HEAD, POST" />
</rule>
<rule name="Public">
<match serverVariable="RESPONSE_Public" pattern="OPTIONS, TRACE, GET, HEAD, POST" />
<action type="Rewrite" value="OPTIONS, GET, HEAD, POST" />
</rule>
</outboundRules>
</rewrite>

In my case works:
<requestFiltering>
<verbs allowUnlisted="false">
<clear/>
<add verb="GET" allowed="true" />
<add verb="HEAD" allowed="true" />
<add verb="POST" allowed="true" />
</verbs>
</requestFiltering>
Please notice that I don't allow OPTIONS.
When I not allow OPTIONS then TRACE was also not allowed.

Related

IIS ARR with wordpress not working from internet Error timeout

I have an IIS server in my network with a domain configured who based on some ARR rules on the web.config shows a wordpress that is installed with xaamp in other server in my network.
So when yo go to example.com it shows the wordpress that its in 192.168.110.104:8080
When I try to access to example.com from my network, seems like the rules works fine and the wordpress content it works properly but when I try to access to the domain example.com from the internet it shows a lot of errors as looks like it's trying to load 'internal resources' form internet? obviously it load without css styles, some images works, some not, so it's a mess.
Errors are timeout like this.
GET http://192.168.100.104:8080/wp-content/themes/astra/assets/css/minified/style.min.css?ver=2.4.4 net::ERR_CONNECTION_TIMED_OUT
In the wordpress I have configured the :
wordPress (URL) as http://192.168.100.104:8080
web url : http://192.168.100.104:8080
Maybe I have to place the domain there instead the local ip?
This is my web.config from the IIS
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<defaultDocument>
<files>
<add value="homepage.asp" />
</files>
</defaultDocument>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="*">
<allowHeaders allowAllRequestedHeaders="true" />
</add>
</cors>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="{C:1}://192.168.100.104:8080/{R:1}" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://192.168.100.104:8080/(.*)" />
<action type="Rewrite" value="http{R:1}://example.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<staticContent>
<clientCache cacheControlMode="NoControl" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Headers" value="X-Requested-With, origin, content-type, accept" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Any ideas? thanks in advance!

Unable to persist cookies after redirecting from External URL back to Action Method in ASP.NET MVC

So as part of the payment process in my site, I have to visit an ExternalURL to validate certain fields and as a result of the Validation completion, I will be getting a POST back to my Action Method with some response variables. The problem that I am facing is that the cookies fail to persist even though I have tried out the following Steps.
Have already explicitly assigned the SameSite Flag for the cookie to be Lax.
Have already made some changes to the Web.config that I will be including below.
Part of the Web.config that I modified.
<system.web>
<authentication mode="None">
<forms cookieSameSite="Lax" requireSSL="false" />
</authentication>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" executionTimeout="500" />
<!-- Added this line for restoring Cookie values after the redirect to an external URI. -->
<httpCookies requireSSL="true" />
<sessionState cookieSameSite="None" cookieless="false" timeout="360" />
</system.web>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="2147483647" />
</webServices>
<scriptResourceHandler enableCaching="false" enableCompression="false" />
</scripting>
</system.web.extensions>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
<!--<rewrite>
<outboundRules>
<clear />
<rule name="Add SameSite" preCondition="No SameSite">
<match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
<action type="Rewrite" value="{R:0}; SameSite=lax" />
</rule>
<preConditions>
<preCondition name="No SameSite">
<add input="{RESPONSE_Set_Cookie}" pattern="." />
<add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=lax" negate="true" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>-->
</system.webServer>
The method from where we call the External URL has this piece of code.
HttpCookie ckpaymentTRID = new HttpCookie("PaResTransactionID");
ckpaymentTRID.Value = resultPaymentObj.TransactionID.ToString();
ckpaymentTRID.SameSite = System.Web.SameSiteMode.Lax;
ckpaymentTRID.Secure = true;
HttpContext.Response.Cookies.Add(ckpaymentTRID);
The method where I receive the POST from the External URL consists of this
var SomeCookiee = HttpContext.Request.Cookies["PaResTransactionID"];
Also, I have browsed through this article here and am aware of the changes pre and post the .NET framework update.
Thanks in advance for the help!!!
Turns all the web.config setting changes were inconsequential as the remaining were actually enough to make the cut. Here is actually how I got a hint about how to solve this issue :
As I was being redirected from my application to the External-URL.....in Google Chrome, under dev tools you get to see the cookies that have been passed... I was always getting a warning saying that "since your cookie is not a secure cookie, chrome by default changes the SameSite setting from None to Lax and so your cookie doesn't persist throughout the request at all.".....which then prompted me to change the web application settings to run as https://localhost rather than http://localhost in VS2019. Once I did that, I saw that I no more needed the explicit HttpCookie or sessionState settings to be modified or in fact placed at all in the web.config and the Cookie value persisted in spite of the External Domain Re-Direction.

Hide server information from wappalyzer in IIS

I want to hide my Web Server and Operating System from Wappalyzer
I removed x-power-by but nothing happens
If you want to hide your technology like asp.net, please just remove response header X-POWERED-By
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
If you want to hide your web server, please download URL rewrite extension and set outbound rule like this:
<outboundRules>
<rule name="response" enabled="true">
<match serverVariable="RESPONSE_SERVER" pattern="(.*)" />
<action type="Rewrite" />
</rule>
</outboundRules>
Remember that Wappalyzer will cache the information. So when you finish setting these configurations, please remember to clean browser cache.
I do it like that in the web.config file:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By"/>
<add name="X-Powered-By" value="Write what you want to show here"/>
</customHeaders>
</httpProtocol>

ASP Session Cookies Removal

Using the following web.config file properties I am not able to have my site either remove a session cookie or force the cookie to use HTTPOnly. I am using a basic classic asp website with the below configuration in my web.config file
<configuration>
<system.web>
<httpCookies httpOnlyCookies="true" />
<sessionState mode="Off" cookieless="true"/>
</system.web>
</configuration>
I have tried to use the following outbound rule to rewrite the URL however when the site gets scanned using Qualys it does not rewrite the cookie before the website is scanned. Here is the below property code that is not working:
<outboundRules>
<rule name="Add HttpOnly" preCondition="No HttpOnly">
<match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
<action type="Rewrite" value="{R:0}; HttpOnly" />
<conditions>
</conditions>
</rule>
<preConditions>
<preCondition name="No HttpOnly">
<add input="{RESPONSE_Set_Cookie}" pattern="." />
<add input="{RESPONSE_Set_Cookie}" pattern="; HttpOnly" negate="true" />
</preCondition>
</preConditions>
</outboundRules>
You could always ask the client to 'kill' the cookie (with code attached below) and hope it does so. If this doesn't happen, it could be that there is a bug on the client side or that a user has copied the cookie out of the browser before the expiration, and copies it back in. Anyway... If you can't find a fix, the workaround would be to kill the cookie EVERYTIME you use it.
HttpCookie cookieToKill= new HttpCookie(cookieName);
cookieToKill.Expires = DateTime.UtcNow.AddDays(-1); //any negative value will do)
Response.Cookies.Add(cookieToKill);

System.Webserver rewrite and secure at the same time

I'm serving Confluence through IIS to end user, here is web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="True" />
</security>
<rewrite>
<rules>
<rule name="RewriteUserFriendlyURL" stopProcessing="false">
<match url="\+" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="{UrlDecode:{REQUEST_URI}}" />
</rule>
<rule name="inbound" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:8090/{R:1}" />
</rule>
</rules>
</rewrite>
<handlers>
<remove name="WebServiceHandlerFactory-ISAPI-2.0-64" />
<remove name="WebServiceHandlerFactory-ISAPI-2.0" />
<remove name="PageHandlerFactory-ISAPI-2.0" />
<remove name="PageHandlerFactory-ISAPI-2.0-64" />
<remove name="PageHandlerFactory-Integrated" />
<remove name="WebServiceHandlerFactory-Integrated" />
<remove name="SimpleHandlerFactory-ISAPI-2.0-64" />
<remove name="SimpleHandlerFactory-ISAPI-2.0" />
<remove name="SimpleHandlerFactory-Integrated" />
<remove name="CGI-exe" />
<remove name="ISAPI-dll" />
</handlers>
</system.webServer>
</configuration>
Confluence runs in it's own process on port 8090
What I want is somehow add confluence as a subfolder to another site so it goes to:
site.com/confluence
site.com is ASP.NET website. I'd like to password-protect /confluence folder.
So, if user logged in to site.com (ASP.NET Membership provider) - they get access to /confluence folder.
Is this possible and how this should be done?
What you are asking for is Delegated Authentication of a IIS Reverse Proxy.
This is technically possible.
You don't want to do this. Because you would need to use ASP.Net authentication to view the website. But then you also need to log in using your confluence log in.
You actually want to use
IIS Reverse Proxy/Application Request Routing (this puts the Confluence website in the "subfolder")
Single Sign-on Integration with ASP.Net Membership.
https://confluence.atlassian.com/kb/single-sign-on-integration-with-the-atlassian-stack-794495126.html
With this solution, Confluence uses Crowd to connect to ASP.Net using OpenID.
I recommend using IdentityServer to expose your ASP.Net Membership Provider to the OpenID api.

Resources