I provide links to external websites in my NodeJS application. These take significant effort to find and I want to track the number of clicks. I prefer to avoid front-end JavaScript as I disable it in my browser. So far I have been using query parameters, such as:
router.get('/redir', async (req, res) => {
let url = req.params.url;
// my own tracking logic
// ...
res.redirect(url);
});
This code fails for links that already contain GET parameters, question marks, and ampersands. I tried this one:
router.get('/redir/:url', async (req, res) => {
let url = req.params.url;
res.redirect(url);
});
and the route is not even called.
How can I track link clicks that already contain ?
and &?
Thanks to the comments, here is one way to do it:
router.get('/redir', async (req, res) => {
let url = req.originalUrl.replace("/redir?url=", "");
// logic: verify that this redirect is authorized to avoid Open Redirect and phishing.
if (authorizedUrls.includes(url)) {
return res.redirect(url);
}
return res.redirect("/404");
});
You should check if the URL is authorized to avoid the Open Redirect, a highly dangerous way of phishing listed as Common Weakness Enumeration 601:
CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks. Extended Description An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance.