Want to block URI containing # special character but the irule doesnt work
Hi Gents,
If some experts can help me to find the reason that why the below URI are not blocking using the irule below. What I understand till now that "#" in the URI doesnt match the irule condition because the browser doesnot forward it to the server, if yes how can I fix it.
URI:
/portal/apps/sites/#/home
Irule:
when HTTP_REQUEST { set uri [string tolower [HTTP::uri]] if { ($uri contains "/portal/apps/sites/#/home") } { HTTP::respond 403 } }
Your understanding is correct, hash fragments are local to the browser and are not sent to the server, you can confirm that using developer tools. So the condition of your iRule will never match as F5 will only see the "/portal/apps/sites/" part.
In our case, the "/portal/apps/sites/" URI includes other apps that are affecting other parts of the application. In order to address this issue, we have specified the URI to include "/#/home", as it is a requirement for our case.
I understand. I think there may be some requests initiated by Javascript that are going behind the scenes to update your content. You should use developer tools and see if there is any request related to your specific URI, if you find any, then try to use it in your iRule
Yes, you're completely right, these links that contain a hash sign are not being forwarded from the browser to the server. But the solution below might help you out. The iRule below needs to be attached to a virtual server with the STREAM-profile enabled. It wil inject a little bit of javascript that inspects all links that are being clicked. When the link contains a hash sign, it will redirect the browser back to the F5.
when HTTP_REQUEST {
# Disable the stream filter by default
STREAM::disable
# LTM does not uncompress response content, so if the server has compression enabled
# and it cannot be disabled on the server, we can prevent the server from
# sending a compressed response by removing the compression offerings from the client
HTTP::header remove "Accept-Encoding"
if { [HTTP::uri] starts_with "/f5/anchor_link_redirect" } {
set href [b64decode [URI::query [HTTP::uri] href]]
HTTP::respond 200 content "<html><head><title>Anchor Link Redirect</title></head><body>User clicked on link that contains a hash sign: $href</body></html>"
}
}
when HTTP_RESPONSE {
if { ([HTTP::header "Content-Type"] starts_with "text/html") } {
STREAM::expression {@</title>@</title>
<script>
document.addEventListener(`click`, e => {
const origin = e.target.closest(`a`);
if (origin && origin.href.indexOf('#') > -1) {
const base64_href = btoa(origin.href);
window.location.href = '/f5/anchor_link_redirect?href=' + base64_href;
}
});
</script>@}
STREAM::enable
}
}
The iRule will show the following output, when a link with a hashtag is clicked.