Skip to content

JS: Add 'prototype pollution in utility function' query#2617

Merged
semmle-qlci merged 17 commits intogithub:masterfrom
asger-semmle:prototype-pollution-utility
Jan 16, 2020
Merged

JS: Add 'prototype pollution in utility function' query#2617
semmle-qlci merged 17 commits intogithub:masterfrom
asger-semmle:prototype-pollution-utility

Conversation

@asgerf
Copy link
Contributor

@asgerf asgerf commented Jan 10, 2020

Adds a query that looks for recursive merge functions that are susceptible to prototype pollution. It doesn't check for user-controlled inputs.

For example, it flags this function as vulnerable:

function merge(dst, src) {
    for (let key in src) {
        if (!src.hasOwnProperty(key)) continue;
        if (isObject(dst[key])) {
            merge(dst[key], src[key]);
        } else {
            dst[key] = src[key];
        }
    }
}

It looks for a property enumeration (the for-in loop above) and a dynamic property write (dst[key] = src[key] above), where three flow paths can be found:

  • From key to the base of the dynamic property write
  • From key to the property name of the dynamic property write
  • From src[key] to the right-hand side fo the dynamic property write

It's relatively expensive as there are a lot of sources and sinks, and the graph pruning does not take into account that we require all three paths to exist. For example, if the base of a dynamic property write is definitely unreachable from a source, it might still try to find paths to the property name and RHS of that property write, even though these paths will never result in an alert.

The latest evaluation shows the first serious conflict I've seen between wall-clock time and tuple counts/DPMs, and I'd like to run a few more evaluations to determine which one tells the truth.

@asgerf asgerf added JS WIP This is a work-in-progress, do not merge yet! labels Jan 10, 2020
@erik-krogh
Copy link
Contributor

What about the FP rate?

You get quite a few results just on nightly.slugs, so I worry that the results will be noisy once deployed on LGTM.

@asgerf
Copy link
Contributor Author

asgerf commented Jan 10, 2020

There's a FP in jQuery due to our imprecise treatment of overloading in general. The rest are TPs as far as I can tell (although whether any user-controlled inputs flow there remains TBD).

@asgerf
Copy link
Contributor Author

asgerf commented Jan 13, 2020

Re-running the evaluation shows the wall clock timing was a fluke. +1 for tuple counts/DPM.

@asgerf asgerf marked this pull request as ready for review January 13, 2020 16:09
@asgerf asgerf requested review from a team and mchammer01 as code owners January 13, 2020 16:09
@asgerf asgerf removed the WIP This is a work-in-progress, do not merge yet! label Jan 13, 2020
@esbena esbena self-assigned this Jan 14, 2020
Copy link
Contributor

@esbena esbena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing! I am floored by how elegant and precise this turned out to be.
I do not think any of my comments require a new evaluation, well done.

I am a little surprised, but happy, that I can not find any places that explicitly requires the recursive merge call. My expectation for the query was that the recursive call was a key requirement that had to be explicit.

@asgerf asgerf force-pushed the prototype-pollution-utility branch from eef0023 to 2245882 Compare January 14, 2020 10:53
@asgerf
Copy link
Contributor Author

asgerf commented Jan 14, 2020

Added a change note, and rebased to fix change note conflict.

I also changed the CWE numbers. Actually I'd like to move both the prototype pollution queries to CWE-471 (modification of assumed-immutable data) but I think I'll do that in another PR.

@esbena
Copy link
Contributor

esbena commented Jan 15, 2020

Excellent.
Ping @mchammer01 for a doc review

Two meta tasks:

  • have you pinged maintainers or our security team about the (relevant) newly discovered vulnerabilities?
  • will you update the tracking issues for the 10 CVEs that inspired this query?

Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asgerf - this LGTM.
I have made a few minor comments and leave it up to you to decide whether they are worth addressing. There is a typo (in in) which needs fixed,
Hope this helps!

One way to cause prototype pollution is through use of an unsafe <em>merge</em> or <em>extend</em> function
to recursively copy properties from one object to another.
Such a function has the potential to modify any object reachable from the destination object, and
the built-in <code>Object.prototype</code> is usually reachable through the special properties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting: is usually reachable through the proto and constructor.prototype special properties.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, again it's fairly technical and I think it's easier to understand the other way.

…help

Co-Authored-By: mc <42146119+mchammer01@users.noreply.github.com>
@asgerf
Copy link
Contributor Author

asgerf commented Jan 16, 2020

Thanks for the review @mchammer01

Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates @asgerf

@semmle-qlci semmle-qlci merged commit 4efc418 into github:master Jan 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants