IIS Rewrite URL Condition Grouping - iis

I'm redirecting my website URLs to mobile with the following conditions:
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_USER_AGENT}" pattern="midp|mobile|phone" />
<add input="{HTTP_X-Device-User-Agent}" pattern="midp|mobile|phone" />
<add input="{HTTP_X-OperaMini-Phone-UA}" pattern="midp|mobile|phone" />
<add input="{StaticRedirects:{R:1}}" pattern="(.+)" />
</conditions>
I want to group these first three conditions together and the last one separately.
Redirect rule must be applied if:
HTTP_USER_AGENT or HTTP_X-Device-User-Agent or HTTP_X-OperaMini-Phone-UA matches the pattern
and {StaticRedirects:{R:1}} matches the pattern
Is there any way for grouping these conditions?
PS: I have nearly 10 rules. Do I have to write first three conditions for each of my rules or is there any tag for all rules?

You can achieve your goal using the distributive law:
(A + B)C = AC + BC
Use a concatenation of variables in the condition input. Use a separator that is not expected in any of variable values. In the example below, the /// sequence is used as a separator:
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_USER_AGENT}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
<add input="{HTTP_X-Device-User-Agent}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
<add input="{HTTP_X-OperaMini-Phone-UA}///{StaticRedirects:{R:1}}"
pattern="(midp|mobile|phone)///(.+)" />
</conditions>

Related

How to allow only certain query string parameters in IIS?

In IIS URL Rewrite, I need to Abort all requests, Excepted those which :
do not have any querystring parameter
or
do have one or more querystring parameters within a limited set of querystring parameters.
Every request with one or more querystring parameters outside of the limited set will get an AbortRequest.
So for example :
https://mysite123/page.html Will be accepted
https://mysite123/page.html?allowed3=ccc Will be accepted
https://mysite123/page.html?allowed1=aaa&allowed2=bbb Will be accepted
https://mysite123/page.html?allowed1=aaa&disallowed4=nope Will be rejected
I've been playing and fiddling for days, but did not come to a working solution.
Here is what I've achieved so far : Parameters allowed1, ... allowed4 are allowed, but any others are not.
So far, this rule is too permissive, because if I specify the "allowed1" parameter with the "z" parameter, the request is accepted... but I want it to be blocked due to the presence of "z".
The tricky part is that I do now know in advance the order of my allowed parameter, nor their number. A valid request could contain the "allowed1" parameter, or the "allowed1" + "allowed3" parameters, or only "allowed4". But the "z" parameter should be rejected, even if one of the whitelisted ones is present.
<rule name="Accept Requests Without parameters, or with Only whitelisted ones" stopProcessing="true">
<match url="(.*)" ignoreCase="true" negate="false"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="((^.{0}$)|(((^|\?|&)(allowed1|allowed2|allowed3|allowed4)=)))" negate="true" ignoreCase="true" />
</conditions>
<action type="AbortRequest"/>
</rule>

Can you use URL_Rewrite rewritemaps to modify ServerVariables in IIS?

So I'm having an issue and not sure if it's even possible.
Here's the scenario. We utilize an F5 loadbalancer with an i-Rule set to send us a header (HTTP_IV-USER) value based on an access token.
We want to query that header, see if it matches a value we have setup in a rewritemap and then change it accordingly.
I haven't seen anyone doing this with servervariables. It makes sense on how to do it in regards to changing an URL... but we'd like to change a header variable.
Basically we're taking the value from the Token, which is a number, and then matching that number to a username in active directory.
Thanks for the help!
Of course, we can use rewritemap to check and replace the value. You could modify the rule below to achieve your requirement.
<rewriteMaps>
<rewriteMap name="StaticMap">
<add key="aaaaaaaaa" value="bbbbbbbb" />
</rewriteMap>
</rewriteMaps>
<outboundRules>
<rule name="rewritemaprule">
<match serverVariable="HTTP_IV-USER" pattern="(.*)" />
<conditions>
<add input="{StaticMap:{HTTP_IV-USER}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" value="{C:1}" />
</rule>
</outboundRules>

IIS URLRewrite - Multiple Conditions Back Reference in Action URL

Trying to use URLRewrite to set up some redirection but retain some (and only some of the query string parameters from the source UR, but running into some problems.
Essentially I need to keep the Google Analytics UTM parameters and move them to the Action URL. Here's the config section or one of my redirects:
<rule name="Anything Else" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="utm_source=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_medium=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_campaign=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_term=(\w+)" />
<add input="{QUERY_STRING}" pattern="utm_content=(\w+)" />
<add input="{QUERY_STRING}" pattern=".*" />
</conditions>
<action type="Redirect" url="https://www.google.com?utm_source={C:1}&utm_medium={C:2}" appendQueryString="false" redirectType="Temporary" />
</rule>
The query string may contain none, one, or all of the UTM parameters, but I need these rules fir in any case, as long as the original URL matches. To this end, we have the LogicalGrouping set to MatchAny, and the final condition being a complete wildcard. Testing the conditions individually gives me the back references {C:1} through {C:5} for the UTM parameters, and while there are no matching parameters in the source URL, or no more than one, the rules work.
The problem appears when I have multiple matching conditions in the source URL. IIS throws a 500 error "The expression "https://www.google.com? {C:2}" cannot be expanded."
Am I barking up the wrong tree? Is this even possible? I have the option of coding an HTTPHandler and handing the conversion there, but I was hoping to do this without introducing custom code to the server.
Within a rule action, you can use the back-references to the last matched condition of that rule. Also within a condition input string, you can use the back-references to the previously matched condition.
With that in mind, a possible way to do what you are trying to do is to use the back-reference from previous condition in the next condition's input:
<conditions>
<add input="{QUERY_STRING}" pattern="(?:^|&)var1=([1-9]\d+)(?:&|$)" />
<add input="%{C:1}%_{QUERY_STRING}" pattern="%(.+)%_.*var2=([1-9]\d+)(?:&|$)" />
</conditions>
Then the action of the rule will look like this:
<action type="Redirect" url="newpage.aspx/{C:1}/{C:2}" appendQueryString="false" redirectType="Permanent" />

IIS URL Rewrite - if query parameter(s) is missing

So this is "not your everyday requirement" for today :)
I want to create a rule that will redirect to some other page only if some query parameters are missing.
i found a few examples that will rewrite/redirect if the parameters exists,
but how do i go about if i want to check if they dont exists?
for example, this will test if the parameters exist and redirect based on that:
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^$" />
<conditions>
<add input="{QUERY_STRING}" pattern="^lon=([^=&]+)&lat=([^=&]+)&zoom=([^=&]+)$" />
</conditions>
<action type="Redirect" url="/{C:1}/{C:2}/{C:3}" appendQueryString="false" />
</rule>
how can i change this rule to test if they do NOT exist?
^((?!regex).)*$ Is the regular expression for does not contain regex.
read more here http://bloggernitin.blogspot.in/2007/12/regex-for-doesnt-contain.html
If you are looking for something like lon=xyz doesn't exists in params then use this regex
^(?!lon=(xyz)) this will check if lon param is not there at the start of string
More examples -
In case you have a case where only zoom param is there is query string and lat/lon are missing
e.g. querystring a) "lat=23&zoom=10" b) "zoom=13"
regex - ^(?!lon=.)(?!lat=.)zoom=([^=&]+)
result - a) no match b) match $1= 13
now you can give default value to other params.

URL Rewriting (IIS) - how to represent an url pattern in match tag

I have a url rewrite rule for my IIS 7 server which is following:
<rewrite>
<rules>
<rule name="topcontent">
<match url=".*">
<action type="rewrite" url="mysite.com/{R:0}"/>
</match>
</rule>
</rules>
</rewrite>
Now I have to provide an exception to this rule, for a particular location, which is 'http://tempurl94.goto.com/?q=x&m=y' where 'http://tempurl94.goto.com' will always be there
in the url, and query parameter q and m may vary. So we have to write different rule for
this url. How to write a different (match url=?).
May be I can write a rule before the 'topcontent' rule and say stopProcessing='true'.
But I need to know what should I write inside <match url=' ? '> and what should I write in <action> tag.
You need to add conditions element to the new rule. Put the new rule before the current one and set stopProcessing to true as you mentioned.
<conditions>
<add input="{HTTP_HOST}" pattern="^tempurl94\.goto\.com$" />
</conditions>

Resources