4

我的页面中有一个文本区域,它是一个 HTML 输入字段。其目的是允许用户注册一个确认 HTML,该 HTML 将在执行特定操作后显示在其用户的浏览器中。您可以将其想象为付款后对贝宝的确认,并将您重定向到一个显示“感谢您的购买”的网站。这已经实现了,但现在我正在考虑用户的安全性(XSS/SQL 注入)。

我想知道的是如何<script> <embed> <object>在我的控制器发布操作中安全地过滤掉某些 html 标签,所以如果我检测到 HTML 中有恶意 html,我会在保存之前停止执行。现在我正在这样做:

[CustomHandleError]
[HttpPost]
[ValidateAntiForgeryToken]
[AccessDeniedAuthorize(Roles = "Admin,CreateMerchant")]
public ActionResult Create(MerchantDTO merchantModel)
{
   if (ModelState.IsValid)
   {
      if (!IsSafeConfirmationHtml(merchantModel.ConfirmationHtml))
      {
         ModelState.AddModelError("ConfirmationHtml", "Unallowed HTML tags inputted");
         return View("Create", merchantModel);
      }
      .
      .
      .
   }
}

我的 IsSafeConfirmationHTML 定义为

private bool IsSafeConfirmationHtml(string html)
{
   if (html.ToLower().Contains("<script") || html.ToLower().Contains("<embed") || html.ToLower().Contains("<object"))
   {
      return false;
   }
   return true;
}

有没有更聪明、更清洁的方法来做到这一点?我的意思是,我不想让误报阻止“对象”、“脚本”等词,但我也不想被将“<”转换为“%3C”等的编码所迷惑。 ..

Ontopic:标签内的间距是否有效?示例:< script > alert("1"); < / script >

4

1 回答 1

1

因此,您可以做的一件事就是在其上运行UrlDecodeHtmlDecode(html 解码可能是多余的,但这取决于您对脚本的处理方式)。

加快检查速度的另一件事是使用预编译的正则表达式。

private static Regex disallowedHtml = new Regex(@"script|embed|object",
     RegexOptions.IgnoreCase);

private bool IsSafeConfirmationHtml(string html)
{
    Match match = disallowedHtml.Match(html);
    return !match.success;
}

静态正则表达式实例消除了除第一次运行之外的每次运行的大部分正则表达式开销,使得正则表达式匹配比运行 3 个单独的包含要快得多。您可以使正则表达式足够复杂,以搜索左尖括号、html 实体和 url 编码字符,匹配这些字符和实际标签名称等之间的任何空格。多年来,Microsoft正则表达式信息已经变得相当不错。

我仍然不会说这可以让您 100% 免受用户(上传者?客户?正确的词取决于您的业务模型是什么)对您网站的访问者运行 XSS 或注入攻击。它们可以指向以 mime 类型 x-application 或类似形式返回的图像或 css 文件。如今,HTML 的变化非常迅速。防止这种情况发生的最好方法是让人类参与批准过程,但是人类会犯错误,计算机可能会被愚弄,而且没有法律规定这两个事件不能同时发生。但是你设置一些保护措施是对的。

于 2012-11-29T19:37:41.087 回答