Match the content within a tag from a Non-HTML response in URL Rewrite - iis

When going through a proxy server (A), any self-referential links sent from the apps server (B) need to be re-written to use the proxy as a host instead.
Here's an example:
Response from (B) contains: path
Proxy (A) needs to rewrite as: path
Normally, this is done by creating an outbound rule that inspects html responses for tags that contain urls, looks for references to to the apps server, and rewrites them.
Here's a normal rule GUI version:
<outboundRules>
<rule name="Outbound Links" preCondition="IsHTML" enabled="true">
<match filterByTags="A, Form, IFrame, Img, Input, Link, Script" pattern="(https?:\/\/proxy|^)\/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true" />
<action type="Rewrite" value="http://apps/{R:2}" />
</rule>
Where IsHTML is defined as:
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="text\/html" />
</preCondition>
The problem is that some of the page content is returned via an XHR request. Minimally, this fails the HTML precondition.
but I can expand the rule to also include content types of xhr
However, URL Rewrite still has trouble parsing the returned text into tags because it is not valid HTML.
Here's an example of what the response looks like:
|6383|updatePanel|ctl00_mainContentPlaceHolder_contentUpdatePanel|
<div id="ctl00_mainContentPlaceHolder_resultsPanel">
path
</div>
...
|0|hiddenField|__EVENTTARGET||0|hiddenField|__EVENTARGUMENT||0|hiddenField|
However, when I do this, I get the error:
Sys.WebForms.PageRequestManagerParserErrorException:
The message received from the server could not be parsed.

You cannot modify XHR requests coming back from the ASP.NET. Doing so would be to attempt a Man In The Middle Attack (which your proxy is acting as), but Microsoft has good reason to prevent.
Here's a dummy message to explore the syntax ASP.NET uses in the response:
1|#||2|52|updatePanel|ctl00_mainContentPlaceHolder_firstUpdatePanel|
<p> New Content For First Update Panel </p>
The header starts with 1|#| | and then the number of updates in the rest of the message (2)
Then each update section follows the pattern:
|char_len|update_type|id_of_field_to_update|
New contents to insert into field
The len in each section must exactly equal the number of characters to follow. So finding and replacing content in these messages is extremely fickle.
The best recommendation is to simply return a relative URL that is server agnostic so the client can be redirected relative to their current domain.

Related

Check if header is present in request with IIS and the value

How could I check if a request header exist on IIS 8 and the value of this header is for example "1234"?
I am trying to response with a 500 error for example if the header is not present or the value is not "1234" so you can´t access if you haven´t the secret value.
it is possible on IIS? I check the all availables server variables but I don´t find any reference to Request headers. https://learn.microsoft.com/en-us/iis/web-dev-reference/server-variables
A request header is an HTTP header that can be used in an HTTP request to provide information about the request context, so I suggest you can try to use custom HTTP headers in a urlrewrite condition:
custom headers need to be preceded by "HTTP_".
substitute dashes with underscores
Eg: in order to retrieve the custom header "x-app-version", you can use "HTTP_x_app_version". So thr urlrewrite config should look like this:
<rule name="test" enabled="false">
<match url="(.*)" />
<conditions>
<add input="{HTTP_x_app_version}" pattern="^1234$" />
</conditions>
<action type="Redirect" url="your url" />
</rule>

Modify requestvalidation in WebAPI (Azure)

We have a Asp.NET web api that handles requests from Android and iOS apps. We started to experience issues with GET requests that contained query strings. A URL like this: http://localhost:10723/api/Locations?userId=32432-a4r2-f32r3 gave this response:
A potentially dangerous Request.Path value was detected from the client (?)
After some debugging I saw that the querystring had been encoded, so the actual request was http://localhost:10723/api/Locations%3FuserId=32432-a4r2-f32r3, and that caused the issue. I can make changes to the apps that will fix this, but since this a app that is in production right now, I am desperately looking for a quick fix in the API that will allow the apps to work now.
What I have tried so far:
<httpRuntime targetFramework="4.5.1" requestValidationMode="2.0" />
<pages validateRequest="false" />
And related httpRuntime web.config tricks.
I have also written a custom request validator.
But everything is telling me that this is something that happens before the pagevalidation and my request validator is hit.
I was able to solve this by adding a rewrite rule for url on the server:
<system.webServer>
<rewrite>
<rules>
<rule name="Allowing querystrings.">
<match url="^(.*)\?(.*)$" />
<conditions logicalGrouping="MatchAny" />
<action type="Rewrite" url="{R:1}?{R:2}" />
</rule>
</rules>
</rewrite>
</system.webServer>

IIS File Download without Extension

I've got a .NET Web API 2 application, I've hooked up the api to send me a file id and from there I get the unique file from the server.
Example:
Download
I need it to be a unique id since there could be multiples of the file in the repo. However, when I try to click the download button I get a :
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I was thinking a re-write rule might be a good action, but I dont really want to rewrite it, i just want to allow anything /api/attachment no matter what the rest.
I've already got one rewrite rule since my page is a single-page-application to direct responses to the Default.cshtml like:
<rewrite>
<rules>
<rule name="Default" stopProcessing="true">
<match url="^(?!Lib|api|Assets|Views|Directives|Services|Controllers|signalr).*" />
<action type="Rewrite" url="Default.cshtml" />
</rule>
</rules>
</rewrite>
any thoughts on best way to achieve this?
I was able to resolve by creating an iframe and setting the src to the download like:
$("body").append('<iframe name="downloadFrame" id="download_iFrame" style="display:none;" src="" />');
and then in the C# I set the header like:
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");

Rewriting custom tag attributes using IIS Url Rewrite 2.0 and ARR

I've developed a custom grid control that uses data-* attributes to configure how the grid is supposed to work (in a similar vein to how Bootstrap data API components work. For a particular deployment, I'm having to proxy my web application into another web application using IIS and Application Request Routing (ARR) + URL Rewrite. The proxying part is all done, I'm currently trying to configure the outbound rules for rewriting urls to match. For instance, I currently have rules set up such as:
Rewrite HTTP redirects by updating the Location: header.
Rewrite Html content for URIs in standard tags (e.g., A, Area, base, etc.)
Rewrite Css content for URI's that are relative (e.g. /cassette.axd -> /blog/cassette.axd).
The last issue I am having, is getting the URL rewrite module to accept my urls in data attributes, e.g., if my grid is such like:
<table data-grid data-query="/api/users/">
Should be rewritten as
<table data-grid data-query="/blog/api/users/">
I stress that all other tags, such as <a href and <img src work as expected and even a custom <property value tag is correctly rewritten. Just seems to by hypenated attributes.
I've tried adding a <customTags> section, with my custom tags in:
<customTags>
<tags name="Bootgrid">
<tag name="table" attribute="data-query" />
<tag name="table" attribute="data-update" />
<!-- This next tag WORKS -->
<tag name="property" attribute="value" />
</tags>
</customTags>
However, the above is not matching any attributes that have a hyphen. Not sure if this is actually solvable or not because I can't see anything in IIS configuration to set these.
Also annoyingly once you've created a set of Custom Tags in IIS, you can't seem to edit them again. :-/
I had the same issue, and it appears (although not confirmed by Microsoft) that IIS cannot handle a custom tag that contains a -
A work around that worked for me was to use another outbound Rule. In this example I am attempting to replace the data-zoom-image attribute within an img tag (You will need to replace the <img with <table and data-zoom-image with data-query in both the "match" and "action"
<rule name="RewriteRelativePathsCustomTags1" preCondition="IsHtml" enabled="true">
<match filterByTags="None" pattern="<img ([^>]*)data-zoom-image="(.*?)"([^>]*)>" />
<action type="Rewrite" value="<img {R:1}data-zoom-image=&quotYOUR VALUE TO REWRITE i.e /blog{R:2}"{R:3}>" />
</rule>
<preConditions>
<preCondition name="IsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
Hope this helps
ARR on IIS seems to have issues with tags that include attributes with a dash (-) in them.
Updating to v3.0.1952 seems to have solved the issue for me, but I'm still investigating.
Rather belated, but this was fixed back in 2015 in the Release To Web version (2.0.1952):
IMPORTANT - Changes in this release
Windows 10 and Windows Server 2016 Support - It is now possible to install URL Rewrite Module 2.0 on Windows 10 or Windows Server 2016 with this release
Custom attributes containing dashes are now supported. This is required as HTML 5 has the following rules for determining HTML attribute names: http://www.w3.org/TR/html-markup/syntax.html#syntax-attributes
Incorporates Hotfix for URL Rewrite 2.0 (June 2014) as in KB2974666

IIS Rewrite 2.0 Module - 404 errors

I've installed the IIS Rewrite 2.0 module via Web Components on my Windows Server 2012.
I've read several articles but I just can't seem to get my simple rewrite to work.
I would like to rewrite http://www.acme.com/news/13/Jan/20 to http://www.acme.com/news.html#20-Jan-13
This is the rule I'm using:
<rule name="news articles" stopProcessing="true">
<match url="^news\/(.*)\/(.*)\/(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="news.html#{R:3}-{R:2}-{R:1}" appendQueryString="false" />
</rule>
When I apply http://www.acme.com/news/13/Jan/20 as my test pattern the rewrite works.
However, if I browse to http://www.acme.com/news/13/Jan/20 I get a 404 error:
Requested URL http://www.acme.com/news.html#20-Jan-13
Physical Path C:\Webs\acme.com\www\news.html#20-Jan-13
The physical file news.html exists and I can browse to it directly.
Is it the that are messing things up? Clearly C:\Webs\acme.com\www\news.html#20-Jan-13 isn't a physical file but I don't know how to solve this problem.
I can of course browse directly to http://www.acme.com/news.html#20-Jan-13 without issue.
Can anyone assist please?
Many thanks in advance.
Cheers,
Mark
According to this "How do write a rewrite rule in IIS that allows HTML anchors?" answer, browsers do not send anything after the # in a URL request to the server. They're markers intended solely for the browser to scroll to on the resulting page.
If you look at the logs, do you see a full request for the page including the anchor tag?
An alternative might be to use some DOM loaded JS to scroll the page to the anchor referenced in the URL (jQuery required):
$(function () {
var a_tag = $("a[name='" + window.location.hash.replace("#", "") +']");
$('html,body').animate({scrollTop: a_tag.offset().top}, 'slow');
});
Although, that likely doesn't solve the intended issue of friendlier URLs.

Resources