如何在JavaScript中安全地将任何内容转换为String

eri*_*old 13 javascript security gecko firefox-addon

如果我有:

var test = {toString: function(){alert("evil code"); return "test";}};
Run Code Online (Sandbox Code Playgroud)

我怎样才能转换test为字符串?没有调用test.toString()和不使用typeof x == "string"支票,因为我想允许非字符串.

注意:这是针对FF扩展处理来自内容页面的js范围的对象.

Cra*_*ker 9

遗憾的是,@Matthew Flaschen(目前已接受)的答案不适用于SymbolES6 / ES2015 的课程:

console.log("" + Symbol("foo"));
// results in an exception: 
//   `Uncaught TypeError: Cannot convert a Symbol value to a string` 
// (at least in Chrome as of this writing).
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/L8adq9y4/

(我不知道为什么,因为Symbol有一个非常好的toString()方法:)

console.log(Symbol("foo").toString());
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/v1rqfhru/

不过有一个解决方案:该String()函数似乎能够将任何值(至少是我尝试过的值)转换为String. toString()如果存在的话它甚至会调用:

console.log(String("A String"));
console.log(String(undefined));
console.log(String(null));
console.log(String({value: "An arbitrary object"}));
console.log(String({toString: function(){return "An object with a toString() method";}}));
console.log(String(function(){return "An arbitrary function"}));
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/6uc83tsc/

所以,把你喜欢的任何东西传递进去String(),你就会得到一个很好的结果。


Ivo*_*zel 5

(toString: function(){alert("evil code"); return "test";})甚至没有在这里解析,它会引发语法错误.我想你想用{}而不是().

通常,您可以使用空字符串和加号运算符来执行强制转换:

""+test;
""+2; // "2"
""+4.5 // "4.5"
""+[1, 2, 3] // "1,2,3"
""+{} // '[object Object]'
Run Code Online (Sandbox Code Playgroud)

但在这里,没有真正的方法可以安全地转换对象.

您可以使用它delete test.toString来删除重写的方法,之后它将回退到返回的常规toString方法'[object Object]'.您还可以将toString方法本身转换为字符串via test.toString.toString().

"function () { alert("evil code"); return "test"; }"
Run Code Online (Sandbox Code Playgroud)

这取决于你在这里想做什么.


Mat*_*hen 5

一种选择是:

Object.prototype.toString.call(test)
Run Code Online (Sandbox Code Playgroud)

这给出:

"[object Object]"
Run Code Online (Sandbox Code Playgroud)

在测试的情况下。基本上,它只提供类型信息。但是,我想知道这里的确切情况是什么。邪恶对象如何加载到页面中?如果他们可以在页面上执行任意代码,那么您基本上就不走运了。除其他事项外,然后可以重新定义Object.prototype.toString

  • `Object.prototype.toString.call(123)` 返回字符串 `"[object Number]"`。可能不是您想要使用的,因为数据(123)丢失了...... (2认同)

cas*_*nca 5

JavaScript允许您修改脚本可访问的几乎任何对象的属性,包括Object.prototype它自身,这意味着任何对象都以您解释的方式容易受到"恶意代码"的攻击.

只保证基元是安全的,因此确保永远不执行"恶意代码"的唯一方法是执行以下操作:

function safeToString(x) {
  switch (typeof x) {
    case 'object':
      return 'object';
    case 'function':
      return 'function';
    default:
      return x + '';
  }
}
Run Code Online (Sandbox Code Playgroud)