起因是HackTM中一道Node.js题(Draw with us),全文没有一点攻击性的东西,也不是漏洞详情

其中有一步黑名单检查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function checkRights(arr) {
  let blacklist = ["p", "n", "port"];
  for (let i = 0; i < arr.length; i++) {
    const element = arr[i];
    if (blacklist.includes(element)) {
      return false;
    }
  }
  return true;
}

而最终需要的object中必须要有n,试了好久没成功,5am3师傅直接把题秒了,tql。发现是用arr[["n"]],来绕过黑名单,去浏览器里试了下,woc,还真可以

上班中午午休的时候(强调:没有摸鱼)去探究了下为什么,首先在MDN上找到了这样的描述

请注意,方括号中的所有键都将转换为字符串类型,因为JavaScript中的对象只能使用String类型作为键类型。 例如,在上面的代码中,当将键obj添加到myObj时,JavaScript将调用obj.toString()方法,并将此结果字符串用作新键。

(全文完

探究源码

一般来说是全文完的,但是为了探究其原理,就去调一下源码,这里调的是v8

首先是获取object属性

getobjectproperty

38行的LookupIterator::PropertyOrElement传入了key,跟进该函数

propertyorelement

将key传入Object::ToName中,继续跟进

toname

IsName的作用为

1
2
3
4
  /**
   * Returns true if this value is a symbol or a string.
   */
  bool IsName() const;

所以,不是string类型就会进入ConvertToName

converttoname

调用了tostring,接下来的获取值的过程就不继续下去了,真·全文完

REF

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects

https://github.com/v8/v8