Forum Discussion

Danny_Arroyo's avatar
Mar 29, 2019

How can I match a uri string that has a Hash symbol"www.mycompany.com/#/site/webpage.html"

We have an HA pair of i2600 F5 LTMs running v13.1.0.8 build 0.0.3. We have an application that is not licensed for use outside of our local network (except for 1 specific url). The application owner is requesting that I open the application's VIP to the internet and only allow that 1 specific url to pass through our VIP from the internet. All other urls that pertain to this application can only be accessed when on our local network.

 

This is easy enough to do using: 1. The matchclass with datagroup and an irule to detect the specific url method 2. Or creating 2 Vips restricted based on source address with an irule to detect the specific url.

 

The problem I am having is that the specific url () contains a hash () sign and is causing my "if logical expression" to fail. My plan was to have the irule look for "Public" and act accordingly.

 

I found a thread that explains that this behavior is because the hash symbol is a special segment character in HTML and is not visible by the F5 (nor is anything after the hash symbol).

 

This is from the thread:

 

its not possible to parse on this specific information. Well, its not a fault of your iRule or even F5, its more a thing of the underlying HTTP standart.In the URI world the Hash-Sign () is called a "Fragment" and is completely suppressed from sending by every browser.scheme:[//[user:password@]host[:port]][/]path[?query][fragment]So everthing after the Hash-Sign never hits the wire and therefor never reaches your F5.

 

That being said, I tried both methods that I listed above and tested by logging the url (within the irule) to the ltm log. It shows only the hostname. The uri is completely missing because the hash symbol is the first thing after the hostname.

 

I also tried to just send everyone that is coming from the internet to (), but that also does nothing (meaning the browser just spins and then times out). I'm thinking for the same reason, but cant be sure. I did this with a static redirect in the irule and when that didnt work, I tried again by statically specifying just the uri in the irule. Niether way worked.

 

Here is the irule I created to send everyone from the internet to the static url using a redirect: (This uses 2 VIPs restricted on source address. Only the VIP that allows internet traffic to the specific hostname has this irule)

 

when HTTP_REQUEST { HTTP::redirect "; }

 

Here is the irule I created to send everyone from the internet to the static url: (This uses 2 VIPs restricted on source address. Only the VIP that allows internet traffic to the spcific hostname has this irule)

 

when HTTP_REQUEST { HTTP::uri "//site/Public/webpage.html" }

 

Here is the irule I created that uses matchclass and the datagroup: (Basically if the URL should only be allowed internaly and if the clientip is from the internet, then discard. All traffic that is not discarded should go to the pool configured in the VIP)

 

when HTTP_REQUEST { if { ![string tolower [HTTP::path]] contains "public"] } { if { !([matchclass [IP::client_addr] equals our_internal_iprange])} { discard } } }

 

If anyone knows of any workaround to this issue, I would appreciate it. Or if I just missed something, please let me know.

 

1 Reply

  • Hi Dany,

    As already stated in the article you've found. You simply can't parse URIs including hash signs. The part after the

    is supressed by the browser...

    Old fashioned websites have used those fragement identifiers to jump into a specific section of an single HTML document. Modern websites (e.g. based on AngularJS) are using those fragement identifiers within client-side JScripts to dynamically load additional content in the background via API calls based on the currently displayed fragment identifier. For API based web applications the URL after the

    is just a client-side thingy to allow the user to create bookmarks for deep nested pages. The HTML pagesyou see are non-existent on your web servers...

    To grant access to just a subset of your web site you would need to fully understand how the fragment identifier is used by your application and how subsequent content is loaded by the browser. You need to fully understand the application logic and the involved API calls and then write an Application Layer Gateway to allow/block specific API calls...

    Sounds terrible for you? I completely agree! And to make it even worse, you will need to review/adjust your homegrown Application Layer Gateway each time the web application gets an update...

    Cheers, Kai