最好的方式来处理安全和避免XSS与用户进入网址
-
03-07-2019 - |
题
我们有一个高度安全的应用程序,我们希望允许用户进入网址,其他用户将会看到的。
这就引出了一个高风险的XSS黑客户有可能输入javascript,另一个用户的结束执行。由于我们保持敏感的数据至关重要的是这永远不会发生。
什么是最好的做法,在处理这个?任何安全白名单或逃模式单独够好?
任何建议,在处理重定向("这个链接去外面我们的网站"上的消息警告页面的链接,例如)
有一个争论不支持用户进入链接在一切?
澄清:
基本上我们的用户要输入:
stackoverflow.com
并把它输出到另一个用户:
<a href="http://stackoverflow.com">stackoverflow.com</a>
我真的很担心被他们使用这一XSS丐。I.e。他们输入:
警报('砍死!');
所以其他用户得到这个的链接:
<a href="alert('hacked!');">stackoverflow.com</a>
我的实例只是解释的风险-我知道,javascript和网址是不同的东西,但是让他们输入后者,他们可能能够执行前者。
你会惊奇的如何许多的网站,你可以打破这种把戏-HTML甚至更糟。如果他们知道要处理的链接,他们也知道来消毒 <iframe>
, <img>
和聪明CSS引用?
我的工作在一个高的安全环境--一个单一的XSS黑客可能会导致非常高的损失对于我们。我很高兴我可以产生Regex(或使用的一个很好的建议迄今为止),可以排除一切,我所能想到的,但那会够吗?
解决方案
如果您认为网址不能包含代码,请再想一想!
https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
阅读,然后哭泣。
以下是我们如何在Stack Overflow上执行此操作:
/// <summary>
/// returns "safe" URL, stripping anything outside normal charsets for URL
/// </summary>
public static string SanitizeUrl(string url)
{
return Regex.Replace(url, @"[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]", "");
}
其他提示
的过程中呈现的一个链接"的安全"应该通过三个或四个步骤:
- 溢/重新编码的字符串你已经给(RSnake已经记录了一些技巧 http://ha.ckers.org/xss.html 即使逃脱,并UTF编码).
- 干净的链接:Regex是一个好的开始-确保以截断串或把它扔掉它是否包含一个"(或任何使用关闭的属性在你output);如果你正在做的链接仅仅作为参考的其他信息也可以生效的议定书》在这个过程结束时-如果该部之前的第一个结肠是不是'http'或"https"后添加'http://'开始。这可以让你创建可用的链接,输入不完整,为用户类型的进一浏览器,并给你最后一次开枪绊倒了什么恶作剧,有人试图偷偷。
- 检查结果是一个良好的形成的网址(protocol://host.域[:port][/path][/[文件]][?queryField=queryValue][#anchor]).
- 可能的检查结果对一个黑名单的网站,或试图获取它通过某种形式的恶意软件检查程序。
如果安全是一个优先我希望的用户才会原谅一点妄想在这个过程中,即使它并最终抛开某些安全的链接。
使用图书馆,例如异-ESAPI API:
- PHP- http://code.google.com/p/owasp-esapi-php/
- Java http://code.google.com/p/owasp-esapi-java/
- .净 http://code.google.com/p/owasp-esapi-dotnet/
- 蟒蛇 http://code.google.com/p/owasp-esapi-python/
阅读以下内容:
- https://www.golemtechnologies.com/articles/prevent-xss#how-to-prevent-cross-site-scripting
- https://www.owasp.org/
- http://www.secbytes.com/blog/?p=253
例如:
$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml
$sanitizer = ESAPI::getSanitizer();
$sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );
另一个例子是使用一个内置的功能。PHP的 filter_var 功能是一个例子:
$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$sanitized_url = filter_var($url, FILTER_SANITIZE_URL);
使用 filter_var
允许 javascript话,并筛选出的计划,既没有 http
也不 https
.使用 异ESAPI消毒剂 大概是最好的选择。
又一个例子是代码 WordPress:
此外,由于没有办法知道其中的URL链接(即,它可能是一个有效的网址,但内容的网址可能会被淘气),有一个谷歌 安全浏览 API你可以叫:
滚你自己的regex对于卫生设施是有问题的几个原因:
- 除非你是乔恩的飞碟,代码将有错误。
- 现有的Api有许多小时的审查和测试。
- 现有的URL-验证Api考虑国际化。
- 现有的Api将保持最新的新出现的标准。
其他问题要考虑:
- 什么计划你允许(被
file:///
和telnet://
可接受的)? - 什么样的限制,你想到的地方内容的网址(均是恶意软件的网址可以接受的)?
输出时只需HTMLEn代码链接。确保您不允许 javascript:
链接。 (最好有一个接受的协议白名单,例如http,https和mailto。)
您没有指定应用程序的语言,我将假设ASP.NET,为此您可以使用 Microsoft反跨站点脚本库
它非常易于使用,您只需要一个包含就可以了:)
当你谈到这个主题时,为什么不阅读设计安全Web应用程序指南
如果有任何其他语言....如果有一个ASP.NET库,也必须可用于其他类型的语言(PHP,Python,ROR等)
在我用JavaScript编写的项目中,我将此正则表达式用作白名单:
url.match(/^((https?|ftp):\/\/|\.{0,2}\/)/)
唯一的限制是您需要将./放在同一目录中的文件前面,但我想我可以忍受。
对于Pythonistas,请尝试使用Scrapy的 w3lib 。
您可以使用十六进制代码转换整个网址并将其发送到您的服务器。这样客户端第一眼就看不懂内容了。阅读完内容后,您可以解码内容网址=?并将其发送到浏览器。
允许使用URL并允许使用JavaScript是两回事。