Should I whitelist? Blacklist? Filter? If so what's the filter? Or should I just pass them to OS?
You should whitelist.You should whitelist. I would go for thea sensible minimum of http:
, https:
, mailto:
and optionally ftp:
. Including more protocols is unnecessary if you don't have a special use case in mind. That said some systems are more permissive than others. The Wordpress docs define this list of safe protocols in their wp_allowed_protocols()
function:
Array of allowed protocols. Defaults to an array containing 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', and 'webcal'.
None of these are inherently unsafe but you will not have any use case for a fax:
or gopher:
URL.
At the same time I'm worried, are there are potentially bad URLs?
There are pseudo-protocols that have side effects. javascript:
URLs should definitely not be possible. The file:
scheme is dangerous as well because local files are often more privileged than web content. For Firefox you especially don't want to allow chrome:
and resource:
URIs.
This is a good example for a problem where only whitelisting works since it's not possible to keep track of all the custom URI schemes and their effects for every single browser.