50 lines
1.2 KiB
JavaScript
50 lines
1.2 KiB
JavaScript
// Runtime require hook for StellaOps Scanner runtime evidence
|
|
// Usage: node -r ./runtime-require-hook.js app.js
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
|
|
const outPath = process.env.SCANNER_NODE_RUNTIME_OUT || path.join(process.cwd(), 'node-runtime-evidence.ndjson');
|
|
const root = process.env.SCANNER_NODE_ROOT || process.cwd();
|
|
|
|
function hashLoaderId(value) {
|
|
return crypto.createHash('sha256').update(value || '').digest('hex');
|
|
}
|
|
|
|
function scrub(p) {
|
|
if (!p) return p;
|
|
try {
|
|
const rel = path.relative(root, p);
|
|
return rel.startsWith('..') ? p : rel.split(path.sep).join('/');
|
|
} catch {
|
|
return p;
|
|
}
|
|
}
|
|
|
|
function emit(record) {
|
|
try {
|
|
fs.appendFileSync(outPath, JSON.stringify(record) + '\n');
|
|
} catch {
|
|
// best-effort: ignore write failures
|
|
}
|
|
}
|
|
|
|
const originalLoad = module.constructor._load;
|
|
module.constructor._load = function (request, parent, isMain) {
|
|
const from = parent && parent.filename ? scrub(parent.filename) : undefined;
|
|
const to = scrub(request);
|
|
const loaderId = hashLoaderId(__filename);
|
|
|
|
emit({
|
|
type: 'edge',
|
|
from,
|
|
to,
|
|
reason: 'runtime-require',
|
|
loaderId,
|
|
isMain: !!isMain
|
|
});
|
|
|
|
return originalLoad.apply(this, arguments);
|
|
};
|