1

Scenario: An app that supports hyperlinks inside content. The app has code to execute the hyperlink that looks like this:

Process.Start(href); // href is the link, e.g. "http://www.google.com"

Question: The user can set arbitrary content in the string, and the app needs to sanitize it and disallow non-URLs such as "foo.exe" that might be local commands or executables. What is the "correct" way to do this? Note: we're not trying to do http blacklisting.

So far we're thinking of parsing this into a System.Uri, and checking that there is a non-empty uri Scheme, e.g. http://. But since this is a potential security issue (a user creating a document with a url and sending the document to someone else who clicks the url) we'd like to know what security experts recommend. For instance, a url with the file:// scheme may be problematic as well.

Edit: This is something I assume any app (browsers, word processors, editors, etc) that supports hyperlinks has to deal with. I'm interested in knowing what the standard behavior is.

bright
  • 4,700
  • 1
  • 34
  • 59

1 Answers1

2

There's a basic way:

try{var url = new Uri(mightBeScary);}
catch {/*oh snap it's not a URL, run!*/}

Of course, this can still allow for this sort of thing:

ftp://how-to-spell-malicious-plx.com/virus.exe

So, a regex to ensure that it is actually an HTTP URL would be the next logical step. Shamelessly stolen but attributed from this wonderful person

private bool IsUrlValid(string url)
{

    string pattern = @"^(http|https|ftp|)\://|[a-zA-Z0-9\-\.]+\.[a-zA-Z](:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*[^\.\,\)\(\s]$";
    Regex reg = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
    return reg.IsMatch(url);
}

The most thorough way to determine if something is a valid URL is to issue a HEAD request, as demonstrated here.

This will make a request and see if something is actually a URL and has a web endpoint. You can then branch based on this determination.

Community
  • 1
  • 1
Codeman
  • 12,157
  • 10
  • 53
  • 91