- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试缓解 XSS。我怎样才能避免这种情况:
jAvascript:alert('test2')
在链接的 href
中?
我已经尝试了以下方法,但它只是将上述字符串的未解析的文字值分配为 href 的相对路径,而不是能够触发代码执行的正确 javascript:
href。我想知道攻击者如何利用这一点。
我试过以下方法:
a = document.createElement('a');
然后这两个:
a.href = 'jAvascript:alert('test2')';
还有这个:
a.setAttribute('href', "jAvascript:alert('test2')");
但两者都返回 "jAvascript:alert('test2')"
然后查询 a.href
,而不是所需的(或不需要的,具体取决于您的观点) ) javascript:alert('test2');
如果我可以解析所有实体,那么我可以解析出结果字符串中出现的所有 javascript:
,这样就安全了——对吗?
我在想的另一件事是,如果有人执行 j&##X58;1;vascript:steal_cookie();
怎么办。我的意思是,从理论上讲,它们可以有无限级的递归,最终都会解决,对吧?
function resolve_entities(str) {
var s = document.createElement('span')
, nestTally = str.match(/&/) ? 0 : 1
, limit = 5
, limitReached = false;
s.innerHTML = str;
while (s.textContent.match(/&/)) {
s.innerHTML = s.textContent;
if(nestTally++ >= limit) {
limitReached = true;
break;
}
}
return s.textContent;
}
最佳答案
A
或 &
等 XML/HTML 字符实体在包含它们的字符串被解析为 XML 或 HTML 时被解码 .通常,当它们作为 HTML 页面的一部分从服务器发送到浏览器时会发生这种情况,尽管还有其他情况(例如在 JavaScript 中分配给 element.innerHTML
)可能导致字符串被解析为 XML 或 HTML。
在 JavaScript 中读取或写入元素属性不会触发 XML/HTML 解析,因此不会扩展字符实体。如果你写
a.href = "jAvascript:alert('test')";
然后 a
元素的 href
属性将是 jAvascript:alert('test')
,& 符号和所有.
需要注意的重要一点是,无论何时将字符串解析为 XML 或 HTML,字符实体都会被解码一次。因此,&x41;
变为 a
,而 A
变为 A
。它不会“最终解决所有问题”,除非您正在做一些愚蠢的事情,比如从 .textContent
读取并重复分配给 .innerHTML
。
一旦解析完成,完全不相关输出中的任何字符序列是否看起来像 XML/HTML 字符实体 — 也就是说,除非您然后获取输出并将其馈送到 XML/HTML 解析器再次。 (这样做很少有用,而且通常只会由于错误而发生,例如在应该分配给 .textContent
时分配给 .innerHTML
。)
无论如何,看看评论,您说您正在编写一些客户端 JavaScript 代码,这些代码从您无法控制的服务器获取一些不受信任的数据,并且您担心只是将数据分配给 .innerHTML
可能允许 XSS 攻击。如果是,则有两种情况:
您收到的数据应该是纯文本。在这种情况下,您应该将它分配给 .textContent
并完成它。
您收到的数据实际上是 HTML。在那种情况下,您确实需要承担对其进行 sanitizer 的艰巨而费力的工作。 This JavaScript HTML sanitizer from the Caja project可能会有帮助。
关于javascript - 如何以编程方式让字符串的所有 unicode 实体自行解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12331195/
我发现以下帖子非常有帮助: How to pickle yourself? 但是,此解决方案的局限性在于,重新加载类时,它不会以其“运行时”状态返回。即它将重新加载所有变量等以及类在转储时的一般状态.
我是一名优秀的程序员,十分优秀!