Hacker News new | past | comments | ask | show | jobs | submit login
Exploiting prototype pollution (securitum.com)
53 points by xtacy on Nov 24, 2019 | hide | past | favorite | 13 comments



The problem here is not prototyping, it's the service accepting executable code from the user.


Agree. Same in ruby

    Object.define_method('env') { { RUBYOPT: "-e puts 123" } }
Though ruby rejects it

    $ RUBYOPT="-e 'puts 123'" env ruby
    Traceback (most recent call last):
    ruby: invalid switch in RUBYOPT: -e (RuntimeError)
https://github.com/ruby/ruby/blob/b753929806d0e42cdfde3f1a8d...

And to use -r file needs to be .rb


Prototype pollution is nasty. You can get into a state where your Node.js server is "poisoned" and all subsequent requests are owned by the attacker, depending on which object is polluted.


"Prototype pollution is a vulnerability that is specific to programming languages with prototype-based inheritance (the most common one being JavaScript)."

Naming is a difficult but critical aspect of conceptualizing a solution [1]. Programming, even when ad-hoc, relies on an internal conceptual model to guide the programmer. It pays to be pedantic with language.

A "prototype" per common understanding and dictionary definition strongly implies the act of "copying". Per that sense, the "prototype" of an Object is distinct object with its own distinct life-cycle and state space trajectory.

So it should be clarified here that the OP exploit is not an inherent weakness of prototype based OO approach, in principle. The Javascript "prototype" is really a "parent delegate". It is a Delegated-Parent Inheritance language, and the OP exploit is a feature/bug of delegate based composition approaches, by definition.

This inability by otherwise (obviously) intelligent people in naming things is an unfortunate pattern in computer science and software development. A historic favorite is "dynamic programming".

[1]: https://martinfowler.com/bliki/TwoHardThings.html


I like "delegate", how would you call `Object.prototype`? And "parent delegate" looks a duplication for me. Children-Parent Inheritance language (like receiving traits by children) and Object With Delegates language:

    ({}).delegate === ({}).constructor.withDelegate
    ({}).parent === ({}).creation.withParent
Oh and `Object` - it is `ObjectConstructor` - though all regular functions are constructors

    constructor sum(a, b) { return a + b }


Maybe it is that I have used a lot of javascript, but "prototype-based inheritance" communicated the idea to me, but "Delegated-Parent Inheritance language" does not.


one thing to note:

  for (key in obj) // do
It’s better to use the first method below (when initializing):

  obj = Object.create(null)
  obj = {}
So you don’t inherit random keys from the chain, unless you intend to. Or use:

  Object.keys(obj).forEach(k
Which doesn’t have this issue like the for-in loop version does.


Not particularly relevant here; the for-in loop here was operating on the `env` object, which holds all the keys directly. The prototype access was via the expression `options.env`, not the for loop.


  obj = Object.create(null)
  obj = {}
is exactly the same as

  obj = {}
I would also do `Object.keys().forEach()`.


It’s not. The null version won’t have methods like hasOwnProperty etc.

If it wasn’t clear, i was mentioning 2 ways of initializing, not that you should reassign immediately.


I see a lot of people accessing a map/dictionary using the “for (key in)” pattern, not realizing they are inheriting any method/prototype names along with their basic dictionary they’ve defined. Using Object.create(null) is an easy way to not only save memory, but reduce issues if using dynamic key names.

https://stackoverflow.com/questions/500504/why-is-using-for-...


    delete Object.prototype.__proto__;
Fixed.


Not at all:

    delete Object.prototype.__proto__;
    a = {};
    a.constructor.prototype.x = 1;
    a.x == 1
Outputs true




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: