
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A library that exposes V8 API inside javascript code.
The V8 API has many useful function and object that helps V8 C++ embedder. NodeJS allow to embed C++ modules with the "require" implementation. However writing C++ code to use the V8 API is somehow too tedious. This library provide pure in-javascript access to some V8 API features. Be warned that not all features are suitable for in-javascript access. Also not all features works as expected.
This section provides required terminology to read the API and the issues. Although exposure is wrapped in "secured" functions, so no call will fall to C++ exception and destroy the NodeJS process, there are cases that doesn't work as expected. If you are familiar with internals of V8 engine version 3.14 and newer, you can skip this section.
Objects in javascript are map from key to something. There are three types of properties:
Note: Interceptors are intentionally not called "properties".
That is the usual value property, it can be any javascript value - primitive, null, undefined, object, function, etc.
Properties of this type does not contain value, but has a pair of functions knows as getter and setter. The getter is called each time someone trying to get the value of that property. The setter (if exists) is called each time someone is trying to set a value to that property.
Example:
document.body.innerHTML = "<b>asd</b>";
This calls internal function of HTMLElement which does not store the string directly, but parses it and modify the DOM tree.
Object.defineProperty(MyClass.prototype, "flag", {
"get": function() {
return this._storage.flag;
},
"set": function(value) {
this._storage.flag = !!value;
}
});
This is one way to define accessor purely in javascript from ECMAScript5.1 version and above. Instances of
MyClass will have a property flag, that when set to any value, will convert it to boolean before store it.
These are not really a properties, but a callback functions set on object. These callbacks are called to determine what properties the object has, when someone trying to get or set property value or even to determine if property is configurable, enumerable or read-only. These are quite useful, when determining the properties of an object are dependent on something external to the object.
There are no way to use interceptors purely in javascript. Interceptors are provided by V8 API and currently have a lot of issues.
Each object in javascript has two source of properties. The local storage of properties is known as "own properties", "local properties" and so on. We will call the storage for local properties - [[Local]]. The prototype storage of properties is known as "prototype properties", "properties on __proto__" and so on. We will call the storage for prototype properties - [[Prototype]]. The square brackets are intentional, because all function have a special property prototype, which although connected to [[Prototype]] it is not the same.
So how this storage spaces are mixed? Each time someone is trying to access a property of an object that property is
searched in [[Local]]. If the property is not found in [[Local]] it is searched on [[Prototype]]. The [[Prototype]]
storage however is an javascript object (the [[Local]] is not). Searching a javascript object repeat the process by
looking that javascript object [[Local]] first, then its [[Prototype]]. This search completes when a property is found
or when a point is reached that there is no [[Prototype]]. The Object.prototype object has null value for
[[Prototype]].
Object
/ \
[[Local]] [[Prototype]]
/ \
[[Local]] [[Prototype]]
/ \
[[Local]] [[Prototype]]
/ \
[[Local]] null
Where the [[Local]] and [[Prototype]] comes from? The [[Local]] is internally created when an object is created.
var o = {};
//Now o has [[Local]] storage.
The [[Prototype]] however is the very same object that is given by prototype property of the function used to construct the object:
var literal = {};
var object = new Object();
//Now "literal" and "object" has Object.prototype for [[Prototype]].
var MyClass = function() {}
var myObject = new MyClass();
//Now "myObject" has MyClass.prototype for [[Prototype]].
//Note: If not modified, the MyClass.prototype has Object.prototype for [[Prototype]].
Because [[Local]] is checked first, the local properties could shadow the prototype properties.
var MyClass = function() {}
MyClass.prototype.foo = "bar";
var myObject = new MyClass();
myObject.foo = "baz";
console.log(myObject.foo); //baz
console.log(MyClass.prototype.foo); //bar
//Now myObject.foo shadows the property with the same name coming from MyClass.prototype
Once an object has an interceptors callback set, they shadow the [[Local]]. However interceptors are API only and they
could return empty handles. These are not handles to any javascript value, including undefined or null.
Returning an empty handle means that "this property is not found within the interceptors". If that is the case, the
search continue with [[Local]] and [[Prototype]] as described above.
Be warned that interceptors are not stored within the object, it stores only callbacks and properties are retrieved by
calling the respective callback instead of searching the [[Local]] or [[Prototype]] storage. Thus this properties are
not real, none of the functions of object containing Real in their name will retrieve those properties (e.g.
Object::HasRealNamedProperty and etc).
Object and
not a Function. It means that typeof object === "object is true and quarks.Value.isFunction(object)
is false.Object.getOwnPropertyDescriptor method does not call interceptors and searches the [[Local]] directly.for...in loop calls enumerate and query interceptors, but ignore DONT_ENUM property attribute.Object.keys method calls only enumerate interceptor and thus ignore DONT_ENUM property attribute.Object.defineProperty method doesn't call any interceptors and set attribute to [[Local]] directly.quarks.Object.setAccessor and quarks.ObjectTemplate.prototype.setAccessor calls
Object::SetAccessor and ObjectTemplate::SetAccessor respectively. Because those methods are exposed to call
C++ functions and not javascript functions, Object.getOwnPropertyDescriptor will not retrieve the callbacks
given. Instead the descriptor will contain a value property which will be the value returned by the getter.FAQs
A library that exposes V8 API inside javascript code.
We found that quarks demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.