Extension messaging bindings avoid using Object.prototype.toJSON and Array.prototype.toJSON by using [1] the safe-builtins version of JSON.stringify() [2]. This is done in order to prevent script from mucking with the serialization by having custom toJSON methods. However, this is totally ineffective: though it protects against Object.prototype.toJSON manipulation, script could still easy pass an object with a toJSON property as a message, like the following:
chrome.runtime.sendMessage({foo: 'bar', toJSON: function() { return '5'}});
In this case, the message received will be '5', rather than {foo: bar}. Because of this, any script that wanted to manipulate the serialization process can do so quite trivially.
In the end, the avoidance of using the [Array|Object].prototype.toJSON methods really only serves to potentially cause confusion - we respect some toJSON implementations, but not others. What's more, there might be potential reasons to use a script-provided toJSON implementation (if, for instance, script wanted to provide its own serialization for functions or special objects).
Now, onto the code history. This was originally added in revision 200dcd387d6902556e41e9439ce64f7f219f5809 (back in 2010) in response to extensions clobbering the JSON.stringify implementation that extensions bindings code used for sending *all* arguments to the browser (as well as parsing function schemas). This would absolutely cause a problem, but is unrelated to JSON message parsing. The message sender and receiver already have the ability to send arbitrary values and mutate and received values, so we aren't protecting against anything here.
Motivation: this would be painful to implement in native bindings, not to mention being unnecessary and less efficient.
Proposal: in native bindings, respect toJSON behavior. In the (hopefully unlikely) event that any extensions are relying on this, this will provide a slow roll out.
There's not much action needed here; this bug is mostly just for tracking, historical, and/or discussion purposes.
[1] https://chromium.googlesource.com/chromium/src/+/1c3de3712cc2d6704930681cc29a17ab89490445/extensions/renderer/resources/messaging.js#107
[2] https://chromium.googlesource.com/chromium/src/+/1c3de3712cc2d6704930681cc29a17ab89490445/extensions/renderer/safe_builtins.cc#103
Comment 1 by bugdroid1@chromium.org
, Jan 31 2018