Contrast Security
npm install @contrast/stashNode/v8 native module for attaching private data to JavaScript objects.
N.B. The key namespace is flat. To minimize the chance of collisions,
it's important to implement namespacing in the string, e.g. @contrast#rasp
instead of @contrast or rasp.
``js
const { Stash } = require('@contrast/stash');
const stash = new Stash('contrast-security##rasp');
const obj = JSON.parse(req.body);
// the following could be stash.setData(obj, true) if no additional
// information is required.
stash.setData(obj, { tracked: true });
// meanwhile, back at the sink...
const trackingData = stash.getData(obj);
if (trackingData) {
// this object is tracked, so check it out.
}
`
The file returns an object implementing the interface defined
in _index.d.ts_.
npm run build will build the project for your current OS and architecture.npm run build:dev passes the --debug flag which can be useful during
development.
npm run download will pull the most recent build artifacts from GitHub.
Simply run npm version and git push && git push --tags.
CI will take care of releasing on version-tagged commits.
test/basic.leak.js is a simple leak detection program that verifies theITERATIONS
basic operation does not leak memory. Run it once with set toITERATIONS
1_000_000 then run it again with set to 2_000_000. The results
from two of those runs follows. N.B. each iteration executes on a 1ms interval
timer so it's not in a hard loop. This causes the test to take about 17 minutes
per million iterations.
`
cooldown 0 - startup {
rss: 41754624,
heapTotal: 270336,
heapUsed: -360016,
external: 1992396,
arrayBuffers: 1993208
}
per iteration { rss: 42, heapTotal: 0, heapUsed: -0, external: 2, arrayBuffers: 2 }
// 2 million iterations
cooldown 0 - startup {
rss: 40701952,
heapTotal: 270336,
heapUsed: -458664,
external: 1992396,
arrayBuffers: 1993208
}
per iteration { rss: 20, heapTotal: 0, heapUsed: -0, external: 1, arrayBuffers: 1 }
*/
`
The benchmark facility uses simple-bench, a benchmarking tool. The benchmark
definition is scripts/simple-bench/benchmark.js and the script to run thescripts/simple-bench/simple-bench.sh
benchmarks is . The shell script rebuildsstash with the class implementation included.
See _.clang-format_.
- 4 spaces for indentation
- open curly brace goes on the same line as the statement
The distringuish repo was the
starting point for this repo. While the code is completely different, the scaffolding
for prebuildify, the scripts, and the CI are all taken from distringuish.
main.cc also contains a C++ class-based implementation instead of the JavaScriptv8::Private::New()
class. It was the first approach and was benchmarked against the second approach, which
turned out to be faster. Defining CLASS_BASED during the compilation will cause that
implementation to be built in addition to the one we're using. It's kept around because:
- it's there and fully tested,
- it's an alternate implementation that uses to create keys.v8::Private::New()
- allows creating anonymous keys while ForApi() (what the second#ifdef CLASS_BASED` with an editor and skip over it.
approach uses) does not.
- it's easy to fold the
How to make a persistent copyable
- https://stackoverflow.com/questions/35248929/prevent-v8local-value-from-being-garbage-collected
Changing the NAPI_VERSION at the top of main.cc can lead to hard-to-decipher errors when building
for versions of node that didn't implement that version.
- https://github.com/nodejs/nan/pull/599
- https://github.com/nodejs/nan/issues/587
v8 Private docs
- https://v8.github.io/api/head/classv8_1_1Private.html
Nan Private docs
- https://github.com/nodejs/nan/blob/main/doc/maybe_types.md#nanhasprivate
N-API Doesn't do persistent strings
- https://github.com/nodejs/node-addon-api/issues/392
node-addon-api (the object-wrap.md example was my starting point)
- https://github.com/nodejs/node-addon-api/blob/main/doc