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



场景:一个支持内容内部超链接的应用程序。该应用程序有执行超链接的代码,看起来像这样:

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

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

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

因此,下一个合乎逻辑的步骤是使用regex来确保它实际上是一个HTTPURL。可耻地被盗,但归因于这个了不起的人

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请求,如下所示。

这将发出一个请求,看看某个东西是否真的是一个URL并有一个web端点。然后,您可以根据此决定进行分支。

最新更新