SAP / project-foxhound

A web browser with dynamic data-flow tracking enabled in the Javascript engine and DOM, based on Mozilla Firefox (https://github.com/mozilla/gecko-dev). It can be used to identify insecure data flows or data privacy leaks in client-side web applications.
GNU General Public License v3.0
80 stars 15 forks source link

Conditions involving tainted primitives #216

Open leeN opened 4 months ago

leeN commented 4 months ago

We are wrapping primitives in objects when tainted. While this is the required way to implement this, it has strange side effects. Generally, number objects (e.g., new Number(42)) behave differently in JavaScript compared to numeric literals (i.e., 42 in this example).

This has quite a few downstream effects and might lead to (potential) changes in program semantics.

For example:

// case 0
if (!(Number.tainted(0))) console.log("no") // prints nothing
// case 1
if (!(0)) console.log("no") // prints no
// case 2
if (!(new Number(0))) console.log("no") // prints nothing

One idea, similar to how the fix with maps (af544cf) is implemented, is to unbox tainted numbers upon usage. I believe @0drai has a fix for this prepared. This seems like a generally valid approach, but might change programs semantics if people have code that effectively works like this: Number.tainted(new Number(42)). By unboxing it, we would lose the information that it originally was an object, and change case 2 above into case 1. I think this should not be overly problematic, but it might be something to keep in mind.

tmbrbr commented 4 months ago

Another complication to the above cases - if we add Boolean tainting as well, the first case should return a tainted boolean object, rather than a primitive boolean. But the actual value should still be correct.