2010-05-10 53 views
0

将字符串中的纯文本链接转换为锚标记的最佳选择是什么?用字符串中的锚标签替换纯文本链接最好的办法是什么? .NET

说例如我有“我今天去搜索了http://www.google.com/”。我想将其改为“我今天去搜索http://www.google.com/”。

由于字符串是用户生成的,因此该方法对于任何类型的XSS攻击都必须是安全的。解析前它们将是安全的,所以我只需要确保没有通过解析URL来引入漏洞。

回答

1

一个简单的正则表达式可以让你得到你想要的,因为你说在解析之前字符串将是安全的。只需使用以下方法。

private static readonly Regex urlRegex = new Regex(@"(?<Protocol>\w+):\/\/(?<Domain>[\[email protected]][\w.:@]+)\/?[\w\.?=%&=\[email protected]/$,]*", RegexOptions.Compiled); 
private static readonly Regex emailRegex = new Regex(@"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})", RegexOptions.Compiled); 
private static readonly IEnumerable<string> disallowedProtocols = new[] { "javascript", "ftp" }; 
private static string ConvertUrls(string s) { 
    s = emailRegex.Replace(
      s, 
      match => string.Format(CultureInfo.InvariantCulture, "<a href=\"mailto:{0}\" rel=\"nofollow\">{0}</a>", match.Value) 
     ); 

    s = urlRegex.Replace(
      s, 
      match => { 
       var protocolGroup = match.Groups["Protocol"]; 
       if (protocolGroup.Success && !disallowedProtocols.Contains(protocolGroup.Value, StringComparer.OrdinalIgnoreCase)) { 
        return string.Format(CultureInfo.InvariantCulture, "<a href=\"{0}\" rel=\"nofollow\">{0}</a>", match.Value); 
       } else { 
        return match.Value; 
       } 
      } 
     ); 

    return s; 
} 
+0

'的JavaScript:警报( 'XSS')' – SLaks 2010-05-10 16:22:47

+1

我改变了我的代码有点禁止某些协议,如 “ftp”,但如果用户刚刚进入 “的javascript:警报( 'XSS')”,我正则表达式不会捡起来,所以你可以放心。 – 2010-05-10 16:35:42

+0

应该可以写出通过你的正则表达式的恶意Javascript(我懒得做一个例子),所以你确实需要禁止'javascript:'。 – SLaks 2010-05-10 17:16:26