我在网站中发现了一些没有对外部数据进行清理的JavaScript(siteName
),但我认为这种方式并不代表问题。当然,最好的办法是过滤它,以便只有预期的值可以与代码交互,并且不会担心意外的输入。但是,当前的设置可能会造成多大的伤害?
var branding = {
'website1.com' : {
color: 'red'
},
'website2.com' : {
color: 'blue'
}
};
var siteName = document.referrer.split('/')[2];
var myElements = document.querySelectorAll(".some-class-name");
for (var i = 0; i < myElements.length; i++) {
myElements[i].style.color = branding[siteName]['color'];
}
答案 0 :(得分:2)
这段代码构思不佳,但我认为它不可开发。
document.referrer.split('/')[2]
提取引荐来源者的主机名。攻击者可能控制主机名,但只能在有限的程度上控制;他们无法在该字段中添加任何内容,以便他们无法注册或设置为域名。
branding[siteName]
是Object上内部属性的名称(如siteName
)或方法名称(如{__proto__
,则可以使 hasOwnProperty
做一些有趣的事情。 1}}。但是,这些属性都不会作为Internet主机名有效,因为它们都没有句点。 __proto__
包含下划线,这些下划线在主机名中甚至无效!
如果siteName
未受约束,则以下['color']
仍会限制此代码。函数(如hasOwnProperty
)不具有color
属性;对象原型也不会,所以这看起来像死路一条。
即使我们假设像某个函数以某种方式这样的奇怪值进入结果,但为.style.color
分配这样的值也不会做任何奇怪的事情。
但是,可以轻松避免漏洞的可能性:
var siteName = document.referrer.split('/')[2];
if (branding.hasOwnProperty(siteName)) {
... everything else ...
}
对于方法名称, Object.hasOwnProperty
为false,而且#34;怪异的&#34;像__proto__
这样的属性;它仅适用于已在对象上显式声明的属性。这会将以下代码限制为仅针对预期的站点名称运行。