【问题标题】:how to prevent xss of href attribute at the server side?如何在服务器端防止href属性的xss?
【发布时间】:2018-07-13 19:10:20
【问题描述】:

在我的网站(服务器端是c#)中,我让用户提交这样的链接:

<a href="$">link text</a>

无论他们输入什么,都只会保留在“href”属性中。我想通过“href”网址阻止 XSS。

现在我检查它是否是 c# 对象 URI 的有效 url。

我的问题是:

  1. 使用 URI 验证 url 是否足以防止 url xss?
  2. 如果没有,我应该如何防止这种xss?

例如,我如何防止有效 url 的 XSS 网络钓鱼攻击: "http://xss.rocks/xss.css"

【问题讨论】:

    标签: c# asp.net .net security xss


    【解决方案1】:

    验证为 URI 是一个好的开始。之后,验证scheme 是白名单选项,例如http/https。之后,确保在输出之前对其进行编码(参见 OWASP 链接)。基本上,您完全按照您对任何 html 属性编码所做的操作,除了您还需要注意恶意方案。

    注意事项:javascript:alert(1);(验证方案)、https://example.com?xss=" onclick=alert(1);//(转义输出)。

    见:

    至于您问题的第二部分,一旦用户单击链接并转到新站点,它就不再是您站点上的 XSS。让用户添加任何 URL 仍然是危险的,即使它不是 XSS 漏洞。他们仍然可以链接到恶意网站、非法内容等。对于这些,您也许可以针对site reputation API like Google provides 进行验证,但即使这样也不是万无一失的。

    【讨论】:

      【解决方案2】:

      要回答您的问题 - 验证为 System.Uri 是不够的。我解决问题的方法:

      1. 不允许任何引号字符或换行符,也许您可​​能需要在查询字符串中接受引号,但现在我完全禁止它们。如果我真的需要它,我可能会改变主意。
      2. 如果检测到任何实体(例如 &amp;amp;),则不允许 - 拒绝该 url
      3. 如果字符串解析为 Uri - 检查方案是否被接受

      此时 url 仍可能类似于 javascript&amp;#58alert(1) - 浏览器将接受 &amp;#58WebUtility.HtmlDecode 由于缺少分号而失败,所以:

      1. 如果在字符串的查询字符串部分之前有一个 & 符号或冒号 - 拒绝它

      这里是代码。

          private static readonly string[] acceptedSchemes = { Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeMailto, Uri.UriSchemeFile };
          private static readonly char[] forbiddenHrefChars = { '"', '\'', '`', (char)10, (char)13 };
          private static readonly char[] forbiddenBeforeQueryString = { ':', '&', '\\' }; // the colon may look surprising, but if we deal with a colon we expect something which parses as URI
      
          /// <summary>
          /// Returns true if the specified string is considered XSS safe href attribute value.
          /// </summary>
          public static bool IsSafeHref(string input)
          {
              if (input.Any(c => forbiddenHrefChars.Contains(c)))
                  return false;
      
              // do not accept any entities
              string href = WebUtility.HtmlDecode(input);
              if (href != input)
                  return false;
      
              // check if the scheme is valid, if specified
              bool isUri = Uri.TryCreate(input, UriKind.Absolute, out Uri uri);
              if (uri != null)
                  return acceptedSchemes.Contains(uri.Scheme ?? "");
      
              int qsIdx = href.IndexOf('?');
              string partBeforeQueryString = qsIdx < 0 ? href : href.Substring(0, qsIdx);
      
              if (forbiddenBeforeQueryString.Any(c => partBeforeQueryString.Contains(c)))
                  return false;
      
              return true;
          }
      

      我相信它不应该允许以任何方式切换 URL 的上下文以作为 javascript 执行。如果你找到破解它的方法,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-11
        • 2011-10-26
        • 2014-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        相关资源
        最近更新 更多