我的页面中有一个textarea,它是一个HTML输入字段。目的是允许用户注册确认HTML,该HTML将在发生特定动作后显示在用户的浏览器中。您可以将它想象为支付宝贝后确认PayPal,并将其重定向到一个网站,上面写着“感谢您的购买”。这已经实现好了,但现在我正在考虑用户的安全性(XSS / SQL注入)。
我想知道的是如何在我的控制器后期操作中安全地过滤出某些html标签,例如<script> <embed> <object>
,所以如果我发现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;
}
有更聪明,更清洁的方法吗?我的意思是,我不想得到阻止“对象”,“脚本”等字样的误报,但我也不想被翻译为“&lt;”的编码所迷惑。到“%3C”或其他......
Ontopic :标签内的间距是否有效?示例:< script > alert("1"); < / script >
?
答案 0 :(得分:1)
因此,你可以做的一件事就是打败编码攻击,就是运行UrlDecode和HtmlDecode(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;
}
静态Regex实例为每次运行都会削减正则表达式的大部分开销,但是第一次运行时,正则表达式比正在运行3个单独的包含更快。你可以使正则表达式复杂到足以搜索开口尖括号,html实体和url编码的字符,匹配这些字符之间的任何空格和实际的标记名称等等。多年来微软regex info已经相当不错了
我仍然不会说这会让您100%安全地从用户(上传者?客户?正确的词语取决于您的商业模式)对您网站的访问者运行XSS或注入攻击。它们可以指向作为mime-type x-application返回的图像或css文件,或者其他类似的文件。而且这些天HTML变化很快。保证不受此影响的最佳方法是让人员参与审批程序,但人类会犯错误,计算机也会被愚弄,并且没有法律规定这两个事件不会同时发生。但你应该采取一些保障措施。