Javascript 如何以编程方式获取所有字符串';要解析自己的unicode实体吗?
我正试图减轻XSS的影响。我怎样才能避免这种情况:Javascript 如何以编程方式获取所有字符串';要解析自己的unicode实体吗?,javascript,regex,security,unicode,xss,Javascript,Regex,Security,Unicode,Xss,我正试图减轻XSS的影响。我怎样才能避免这种情况: jAvascript:alert('test2') 在链接的href中 我尝试了以下方法,但它只是将上述字符串的文本、未解析值指定为href的相对路径,而不是能够触发代码执行的适当的javascript:href。我想知道攻击者是如何利用这个漏洞的 我尝试了以下方法: a = document.createElement('a'); 然后这两个: a.href = 'jAvascript:alert('tes
jAvascript:alert('test2')
在链接的href
中
我尝试了以下方法,但它只是将上述字符串的文本、未解析值指定为href的相对路径,而不是能够触发代码执行的适当的javascript:
href。我想知道攻击者是如何利用这个漏洞的
我尝试了以下方法:
a = document.createElement('a');
然后这两个:
a.href = 'jAvascript:alert('test2')';
这是:
a.setAttribute('href', "jAvascript:alert('test2')");
但是在查询a.href
时,两者都返回“jAvascript:alert('test2')”
,而不是期望的(或不期望的,取决于您的视角)javascript:alert('test2')代码>
如果我可以得到所有要解析的实体,那么我就可以解析出结果字符串中出现的所有javascript:
,并且是安全的——对吗
我在想的另一件事是,如果有人做了j&X;1.vascript:steal_cookie()代码>。我的意思是,理论上,它们可以有无限级的递归,并且最终都会解决,对吗
编辑:这段代码看起来怎么样?
只要内容格式正确,就可以使用XML安全地解析它。类似这样的事情,至少作为一个起点():
函数getXmlDoc(s){
var解析器;
if(DOMParser){
parser=新的DOMParser();
xmlDoc=parser.parseFromString,“text/xml”);
}否则{
//即
xmlDoc=新的ActiveXObject(“Microsoft.XMLDOM”);
xmlDoc.async=false;
xmlDoc.loadXML;
}
返回xmlDoc;
}
var xml=getXmlDoc(“ja;vascript:alert('test2'));
警报(xml.documentElement.firstChild.nodeValue);
但是,我可能只是逃避不安全的角色:
function safeEscape(s) {
return s.replace(/[\&\<\>]/g, function($0) {
switch($0) {
case '&': return '&';
case '<': return '<';
case '>': return '>';
}
});
}
安全逃生功能{
返回s.replace(/[\&\]/g,函数($0){
交换机(0美元){
大小写“&”:返回“&;”;
案例“”:返回“”;
}
});
}
对于递归转义字符,您不应该遇到任何问题,因为这是不允许的。缓解XSS的最佳方法是使用输出所处上下文(HTML、HTML属性、CSS、JS等)的适当编码方法对呈现到屏幕上的所有不可信输出进行编码
即使您设法解决了这个问题,也可能有其他攻击向量使用了您没有想到的编码。黑名单过滤器很少(如果有的话)是保护站点的最有效的方法
我不确定您使用的是哪种服务器端语言,但可能有编码lib。可用于多种语言,并为此目的而构建(以及许多其他语言)
更新:因为您需要使用JavaScript来实现这一点,所以您可能需要查看它的JS版本,它看起来可以满足您的需要。我没有测试过它,但如果它像ESAPI一样工作,那么它可能会解决您的问题
要了解有关每个上下文的正确编码的更多信息,请检查和#x41等XML/HTML字符实体代码>或&代码>在包含它们的字符串被解析为XML或HTML时被解码。通常,当它们作为HTML页面的一部分从服务器发送到浏览器时会发生这种情况,尽管还有其他情况(例如在JavaScript中分配给element.innerHTML
)会导致字符串被解析为XML或HTML
读取或写入JavaScript中的元素属性不会触发XML/HTML解析,因此不会扩展字符实体。如果你写信
a.href = "jAvascript:alert('test')";
然后该a
元素的href
属性将是jA;vascript:alert('test')
、符号和所有符号
需要注意的是,每当字符串被解析为XML或HTML时,字符实体都会被精确解码一次。
因此,&x41代码>变为a
,而&#x41代码>变成和#x41代码>。
它不会“最终解决所有问题”,除非你在做一些愚蠢的事情,比如反复阅读.textContent
并分配给.innerHTML
一旦解析完成,输出中的任何字符序列是否看起来像XML/HTML字符实体就完全不相关了——也就是说,除非您获取输出并再次将其通过XML/HTML解析器。(这样做很少有用,而且通常只会在本应分配给.textContent
的情况下,由于分配给.innerHTML
等错误而发生)
无论如何,看看这些评论,您说您正在编写一些客户端JavaScript代码,从您无法控制的服务器获取一些不受信任的数据,您担心仅仅将数据分配给.innerHTML
就可能允许XSS攻击。如果是,则有两种情况:
您收到的数据是纯文本。在这种情况下,您只需将其分配给.textContent
,然后就可以使用它了
事实上,您收到的数据是HTML。在这种情况下,你确实需要承担艰难而艰苦的消毒工作。也许会有帮助
你认为这些标签或URL来自哪里?你是否允许用户输入在页面或其他地方产生链接?我认为这里唯一相关的是它被认为是恶意的。但基本上,这是一种伪标记,我正在从JSONP推特提要解析为html(我不控制所有提要)很酷,谢谢!然而,有两个问题:1)它是否解释了双重嵌套实体?2) 您对我上面附加的伪解决方案有什么想法吗?@adlwalrus:Double-nested entities是非常好的,只要您不通过XML/HTML解析器两次输入相同的字符串(通常不应该这样做)。逃避的全部意义在于我可以写“和”
function safeEscape(s) {
return s.replace(/[\&\<\>]/g, function($0) {
switch($0) {
case '&': return '&';
case '<': return '<';
case '>': return '>';
}
});
}
a.href = "jAvascript:alert('test')";