Apologies, I seem to have mis-read/interpreted your original question with the masking/redirect. They are two different things, but I understand what you mean.
You want to have a URL shortener without using bitly et.al. I suppose. As you already noted, your rule causes a infinite loop. The only way you could get around that is to have
as the rule will not match twice.
You could map a path (e.g.
/in) that is specifically for inbound links
/in/hello -> /hello?utm_source=foo and
/in/wicked -> /wicked?utm_source=foo. But you would have to manage a lot of redirects (perhaps) and every time you wanted to add a new one, would need to redeploy your site.
You might find a solution like Bitly, or others better suit your needs.