Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe Process.Start implementation for untrusted URL strings

My goal is to safely open a web page in a users default browser. The URL for this web page is considered "untrusted" (think of it as a link in a document opened with this software, but the document could be from anywhere and the links in it could be malicious)

I want to avoid someone passing "C:\Windows\malicious_code.exe" off as a URL

My current thought is to do something like this:

Uri url = new Uri(urlString, UriKind.Absolute);
if( url.Scheme == Uri.UriSchemeHttp || url.Scheme == Uri.UriSchemeHttps )
{
   Process.Start(url.AbsoluteUri);
}

Am I forgetting about anything else that my 'urlString' might contain that makes this dangerous (e.g. a new line character which would allow someone to sneak a second process to be started in after the URL or a possible execution of a relative executable starting with http)?

I'm pretty sure both of those cases are handled by this (as I don't believe Process.Start allows you to start two processes as you would in a BATCH file and this should only allow strings starting with http: or https: and are valid urls)

Is there a better way to do this in C#?

like image 674
userx Avatar asked Nov 14 '22 07:11

userx


1 Answers

What you want to check is the scheme of the url (i.e. ftp://, http://, file://, etc.) Here is a list of schemes: http://en.wikipedia.org/wiki/URI_scheme#Official_IANA-registered_schemes

To find the scheme of a URL, use:

Uri u = new Uri("C:\\Windows");
String scheme = (u.GetLeftPart(UriPartial.Scheme).ToString());

For me, the above example gives file://. Just check the scheme, using the code above, and reject the ones you want to filter. Also, surround the parsing with a try-catch block and if an exception is caught, reject the URL; it can't be parsed so you shouldn't trust it.

If you want to ultra-paranoid-safe, you could always parse the URL using a URL parser and reconstruct it, validating each part as you go along.

like image 62
Chris Laplante Avatar answered May 19 '23 22:05

Chris Laplante