如何将超链接与可以在本地执行的任何内容区分开来?

How to differentiate a hyperlink from anything that could execute locally?

场景:支持内容内部超链接的应用程序。该应用程序具有执行超链接的代码,如下所示:

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

问题:用户可以在字符串中设置任意内容,应用需要对其进行清理并禁止非 URL,例如 "foo.exe" 可能是本地命令或可执行文件。 "correct" 的方法是什么?注意:我们不是尝试将 http 列入黑名单。

到目前为止,我们正在考虑将其解析为 System.Uri,并检查是否存在非空 uri Scheme,例如http://.但由于这是一个潜在的安全问题(用户创建带有 url 的文档并将文档发送给单击 url 的其他人),我们想知道安全专家的建议。例如,带有 file:// 方案的 url 也可能有问题。

编辑:这是我认为任何支持超链接的应用程序(浏览器、文字处理器、编辑器等)都必须处理的问题。我很想知道标准行为是什么。

有一个基本的方法:

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

当然,这样的情况还是可以的:

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

因此,确保它实际上是 HTTP URL 的正则表达式将是下一个合乎逻辑的步骤。无耻地盗用但归因于 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);
}

确定某物是否有效的最彻底方法 URL 是发出 HEAD 请求,如 here 所示。

这将发出请求并查看是否有东西实际上是 URL 并且具有 Web 端点。然后您可以根据此确定进行分支。