IIS Request Filtering Allow URL - regex

I am using IIS7 request Filtering (WebSite level) with 'Allow unlisted file name extensions' set to un-checked. After this setting when I access my web application say, _http:/machine_name/app1 then it fails. After adding correct file extensions under 'file name extensions' it starts functioning but it later fails when I surf other links inside my application. I found that I need to add URL's under 'Allow URL' but I do have huge number of URL list which need to be added for e.g.:
'/app1/prop1', '/app1/prop1/services/', '/app1/prop2/repository'..... and more
So, I see a pattern like /app1/* but 'allow URL don't allow any pattern matching. Is there any way to add Regular expression somewhere in IIS so that the matching URL's can be allowed.
Thanks in advance.

I think URLs like '/app1/prop1', '/app1/prop1/services/', '/app1/prop2/repository' don't work with 'Allow unlisted file name extensions' set to false because you didn't allow extensionless requests.
To allow extensionless requests, add <add fileExtension="." allowed="true" /> to your web.config as below:
<system.webServer>
<security>
<requestFiltering>
<fileExtensions allowUnlisted="false">
<add fileExtension="." allowed="true" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
Please let me know if this helped or the issue still occurs.

OK, at last I got the solution. The trick was not using 'requestfiltering' but 'URL rewrite'. It has the option to allow or deny URL based on the regular expression or Wildcard with the option 'Does not match the pattern'. I created rule for the URL/file which does not matches my application's pattern and deny those by redirecting a 404 type of error.

#alexander-abakumov is correct. When allowUnlisted=false, one must include the provided xml (<add fileExtension="." allowed="true" />) to allow extension-less requests (e.g. /App/ or /Folder/).
Request Filtering Limitations
You're correct to use URL Rewrite for achieving RegEx pattern matching. Below are the limitations of Request Filtering.
Stateless - Request Filtering has no knowledge of application or session state. Each request is processed individually regardless of whether a session has or has not been established.
Request Header Only - Request Filtering can only inspect the request header. It has no visibility into the request body or any part of the response.
Basic Logic - Regular expressions and wildcard matches are not available. Most settings consist of establishing size constraints while others perform simple string matching.
Still use Request Filtering
I would still recommend using Request Filtering since it operates so early in the IIS request pipeline; even before URL Rewrite. This gives you the opportunity to immediately discard bad requests. URL Rewrite can then be a second layer of request filtering.
IISRFBaseline
The information above is based on my PowerShell module IISRFBaseline. It helps establish an IIS Request Filtering baseline by leveraging Microsoft Logparser to scan a website's content directory and IIS logs.
For the fileExtensions setting there are two methods for establishing a baseline:
IIS Logs - by parsing prior successful requests and determining the extension of the request.
Content Directory - scanning the file system of the website content directory to see what file extensions are in use.
There are caveats to these two approaches which are described in more detail here. With two techniques, a markdown file is provided describing the methodology of each as denoted by the suffix IIS or FS.
fileExtensions_FS
fileExtensions_IIS
The result of these two techniques are combined, after removing bad requests, to create a baseline for this Request Filtering setting.

Related

How to manage Cookies are required error page?

I am new to jmeter. I record my script using blazemeter chrome plugin. Now in login I am getting Cookies are required Cookies are disabled on your browser. please enable cookies and refresh this page I have set CookieManager.save.cookies=true but no luck .
As per JMeter project main page:
JMeter is not a browser, it works at protocol level. As far as web-services and remote services are concerned, JMeter looks like a browser (or rather, multiple browsers); however JMeter does not perform all the actions supported by browsers. In particular, JMeter does not execute the Javascript found in HTML pages. Nor does it render the HTML pages as a browser does (it's possible to view the response as HTML etc., but the timings are not included in any samples, and only one sample in one thread is ever displayed at a time).
So if your page is using JavaScript in order to check user cookies there is no way to bypass this message, it means that you can just ignore it.
However if you cannot proceed further it means that JMeter doesn't send necessary Cookie header so make sure to add HTTP Cookie Manager to your test plan.
If you added the HTTP Cookie Manager but still seeing that the real browser sends cookies and JMeter doesn't (or sends partial) most probably it means that your server returns malformed or expired cookies and you need to raise a defect for your application.
And last but not the least, if you have to live with these malformed/broken cookies and still need to log in you can go for the following workarounds:
Change "Implementation" of the HTTP Cookie Manager to something less restrictive, i.e. netscape
Add the next line to user.properties file (lives in "bin" folder of your JMeter installation:
CookieManager.check.cookies=false
Increase JMeter logging verbosity for the HTTP Cookie Manager by adding the next line to log4j2.xml file:
<Logger name="org.apache.jmeter.protocol.http.control" level="debug" />
this way you will be able to figure out what's wrong with the cookies
And last but not the least you can always manually extract cookies from the Set-Cookie response header using i.e. Regular Expression Extractor and again manually add them to the HTTP Cookie Manager or HTTP Header Manager

Create a redirect rule for Azure CDN in Verizon which adds /index.html to the end of URL

I created an Azure CDN under Verizon Premium Subscription in the Azure portal with an endpoint which points to my Azure Static Website URL.
I want to create a redirect rule in Azure Verizon engine which adds /index.html to the end of URL if no extension is specified or the last sing of URL is not a / symbol.
So far I tried to use (.+\/[^\.]\w+$) regex expression, you can see an example of how it works here
My first approach:
In this case, if you type the URL https://blah.com/foo/bar in the web browser
it doesn't change the URL however you are able to view some of the content of the existing file from https://blah.com/foo/bar/index.html but some of the links to resources are broken. Not sure why I'm not getting the 404 in this case but maybe its because that I set the Index document name to index.html in the Static Website panel in the Storage account panel in Azure. If I open the Network tab in the developer tools of Chrome I can see a lot of 404 responses e.g.
And its because the website tries to get resources from the https://blah.com/foo/ directory instead of https://blah.com/foo/bar/
So, for example, the loadcsh.js in fact is located under the https://blah.com/foo/bar/loadcsh.js but the website is searching for the file under the wrong directory https://blah.com/foo/loadcsh.js
My second approach
In this case, if you type the URL https://blah.com/foo/bar
it makes a redirect to https://blah.com/foo/bar/foo/bar/index.html
so the foo/bar/ is redundant here.
My third approach
In this case, if you type the URL https://blah.com/foo/bar
it makes a redirect to https://blah.com/index.html
I have no idea how to apply the rule which makes a redirect from https://blah.com/foo/bar
to https://blah.com/foo/bar/index.html and is generic for all such cases.
Any ideas??
Cheers
I think your Regex expression is ok. You can add the rule URL redirect, in the Source textbox you type your Regex expression (.+\/[^\.]\w+$) and in the Destination textbox add https://%{host}/$1/index.htm. Here I used the HTTP variable for Azure CDN which can be used in Verizon. You can read more about the variables here.
In short words the %{host} returns a host name e.g. www.contoso.com
Please keep in mind all rule changes will require couple of hours propagation before it takes an effect on the CDN.

What does the Sitecore.Security.AntiCsrf do and can I disable it on my Content delivery server

We are currently having an issue where some ajax requests to async Controller actions are hanging when an exception is thrown inside the action.
When viewed through the currently executing requests you can see the following information
<REQUEST REQUEST.NAME="c500100080026ded" Url="/url" Verb="GET" Stage="SendResponse" Module="SitecoreAntiCSRF" Time="1602531" SITE.ID="2" WP.NAME="14268" APPPOOL.NAME="AppPool" />
Is the module needed on Content Delivery servers? Can I completely remove it? What would be the implications if I do so?
The version of sitecore: 8 Update-5
The module is designed to protect WebForms from CSRF attacks.
By default, it is configured to protect Sitecore interfaces (Sitecore shell) only. However, it supports configuration and can be enabled to protect frontend solutions.
Since Sitecore shell site is disabled on Content Delivery servers the module can safely be disabled or completely removed without any implications.
If you have Sitecore backend enabled on Content Delivery servers the module can be configured to skip processing requests to some specific locations. Just add a node to Sitecore.AntiCsrf.config file and specify url to filter.
The AntiCSRF module validates a cookie value (a Guid) against a form field value. If your API calls don't contain both of these then the module will raise an error. Interestingly, it doesn't appear to matter what the value actually is.
The module itself injects a Guid::ToString("D") but the check doesn't attempt to parse it back into a Guid, or identify if it is the right Guid. Not sure how good an anti-CSRF check this is, but that aside, the only actual requirement is that the form field name in the request payload must match the #formFieldName attribute of the <AntiCsrf /> element, and the cookie name must match the value of #cookieName.
You mentioned that you tried adding ignore rules - that's the appropriate way to disable the functionality for your use case. I would work on getting this right - it's most likely the rule was not well crafted (or the assumptions about what the rule was testing against were not correct). Below is a sample of a correctly formatted block.
<rule name="WFFM">
<urlPrefix>/sitecore/shell</urlPrefix>
<ignore wildcard="/sitecore/shell/Applications/Modules/Web Forms for Marketers/Form Reports*\?*Cart_*_Items_Callback=yes"/>
<ignore wildcard="/sitecore/shell/~/xaml/Sitecore.Forms.Shell.UI.Dialogs.LookupRecords.aspx*"/>
<ignore wildcard="/sitecore/shell/~/xaml/Sitecore.Forms.Shell.UI.Dialogs.ListItemsEditor.aspx*"/>
</rule>
Note that #wildcard rules are executed as a Regex with IgnoreCase. You can also use #contains. These values, along with <urlPrefix> should not include a scheme, and while <urlPrefix> is necessary to enable the subsequent matching rules, it is not sufficient on its own.
The other thing you can do is set the #detectionResult value to RaiseException and set your Sitecore logging to at least WARN so that you can see the errors being raised in the Sitecore log - these may help you identify the part of the check that is failing. The actual logging in the module isn't great so you won't get much benefit from DEBUG logging I'm afraid.

HAProxy and reqrep path rewriting with redirect configuration

With HA Proxy 1.5 I need to rewrite URL from
http://main.domain.com/my-foo
to
http://othersite.com:8081/other-bar
Here is what I tried:
frontend ft_def
bind :80
mode http
acl has_special_uri path_beg /my-foo
use_backend def if has_special_uri
default_backend def
backend def
mode http
option forwardfor
reqirep ^([^\ ]*\ )/my-foo(.*) \1/other-bar\2
server myserver othersite.com:8081
This works:
URL
http://main.domain.com/my-foo/home.html
becomes
http://othersite.com:8081/other-bar/home.html
and in the browser the initial URL http://main.domain.com/my-foo/home.html appears.
It is exactly what I need: it is completely transparent for the user.
But redirect does not work: when I click on a link on the page the URL is then
http://main.domain.com/other-bar/page2.html
I would like to get http://main.domain.com/my-foo/page2.html instead appearing in the browser.
Is it possible with HA Proxy? I tried many configurations without success.
Thanks!
If you're talking about links in HTML (as opposed to, say, Location: headers for redirects)... HAProxy 1.5 won't be able to modify those.
Presumably, based on what you describe, the page /other-bar/page1.html is internally linking to <a href="/other-bar/page2.html"> when it really should link to <a href="page2.html">. You'd need relative links in order for something like this to work transparently... otherwise, component "X" in your chain will have to be able to modify links on the fly in the response body, but only links, of course, since you wouldn't want to blindly regex-replace the page contents as a whole... and HAProxy 1.5 doesn't munge response bodies, so it can't fulfill the role of component "X."
HAProxy 1.6 might be able to do this, with Lua, but that's a maybe... and if it can be made to do it, it isn't likely to be at the level of performance you'd typically expect from HAProxy, because scrubbing the html in Lua is probably going to be a relatively expensive proposition.
Normally any URL changes should be handled by the web app itself, e.g. there is a :path option under :url configuration in Phoenix.Endpoint for the Phoenix framework: https://hexdocs.pm/phoenix/Phoenix.Endpoint.html, which was specifically designed for this purpose. Then the browser will still request the URL appears in the HTML file but HAProxy will always rewrite it.

Cookie Manager of Apache JMeter doesn't add the cookie to POST request

I build up very simple test plan.
Login: POST, a session cookie is returned.
Get the state: GET, a user state is returned.
Create a resource: POST, JSON body is supplied for the resource.
So my 'Test Plan' looks like:
Test Plan
Thread Group
HTTP Request Defaults
HTTP Cookie Manager
Login (HTTP Request Sampler: POST)
Get State (HTTP Request Sampler: GET)
Create Resource (HTTP Request Sampler: POST)
The cookie generated by 'Login' is added to 'Get State' correctly.
But 'Create Resource' has NO cookie. I changed their order but it doesn't help.
I used the default options firstly and changed some options but it also doesn't help.
Is it a bug of JMeter? or just POST http request is not able to have cookie?
Please give me any advice.
[SOLVED]
I noticed that it is related to the path, not the method.
You'd like to look at the domain of the cookie as well as the path.
I mean, the path and the domain of a cookie could be defined in the server side through Set-Cookie header.
Another solution is to set CookieManager.check.cookies=false in jmeter.properties usually sitting besides the jmeter startup script in bin.
JMeter for some reasons thinks that you can't set the path=/something in a cookie if you are on http:/somesite/somethingelse. That is the path has to match the path your currently on.
I've never seen a browser enforce this limitation if it actually exists. I've seen and written several sites that use this technique to set a secure cookie and then forward someone say to /admin.
I wish this option was at least in the GUI so I didn't have to change the properties file. I think BlazeMeter is smart enough to turn off checking where flood.io is not. If it were up to me I'd just remove the code that checks this entirely. Why make the load tester any harder then it needs to be.
I had this turned on in my Spring Boot server which was causing the issue with CookieManager in jMeter:
server.servlet.session.cookie.secure=true
Removing this made the cookies flow ! Of course this is for localhost. For Production you may need this turned on.