
Ein entwickler- und sicherheitsingenieurfreundliches Paket zur Sicherung von NodeJS-Anwendungen.
Node Security Shield (NSS) ist ein quelloffenes Runtime Application Self-Protection (RASP)-Tool, das die Lücke in der umfassenden NodeJS-Sicherheit schließen soll, indem es Entwicklern und Sicherheitsingenieuren ermöglicht zu deklarieren, auf welche Ressourcen eine Anwendung zugreifen darf.
Inspiriert von der Log4Shell-Schwachstelle (CVE-2021-44228), die ausgenutzt werden kann, weil eine Anwendung beliebige Netzwerkaufrufe tätigen kann, haben wir festgestellt, dass eine Anwendung einen Mechanismus benötigt, mit dem sie erklären kann, welche Berechtigungen sie zulässt, um die Ausnutzung solcher Schwachstellen durch die Implementierung zusätzlicher Kontrollen zu erschweren.
Um dies zu erreichen, verfügt NSS (Node Security Shield) über eine Ressourcenzugriffsrichtlinie (RAP).
Die Ressourcenzugriffsrichtlinie ähnelt der CSP (Content Security Policy).
Sie ermöglicht es dem Entwickler/Sicherheitsingenieur zu deklarieren, auf welche Ressourcen eine Anwendung zugreifen soll. Und Node Security Shield wird dies durchsetzen.
npm install nodesecurityshield
// Node Security Shield einbinden
let nodeSecurityShield = require('nodesecurityshield');
// Angriffsüberwachung und/oder -blockierung aktivieren
nodeSecurityShield.enableAttackMonitoring("Unique-App-Id", resourceAccessPolicy, callbackFunction);
const resourceAccessPolicy = {
"outBoundRequest": {
"blockedDomains": ["compromised.domdog.io"],
"allowedDomains": []
},
"executedCommand": {
"allowedCommands": ["pwd", "(node)[](https://github.com/domdogsec/nodesecurityshield/blob/HEAD/helper%5C/)[a-z|0-9]*(.js)"]
}
};
outBoundRequest: definiert das akzeptierte Verhalten für ausgehende Anfragen
executedCommand: definiert das akzeptierte Verhalten für Befehlsausführung
allowedCommands-Array akzeptiert String. Sie können einen Regex übergeben, um ein Muster von Befehlen zuzulassen.executedCommand definiert hat.pwd zur Ausführung erlaubt und.js-Dateien innerhalb von helper als Node-Prozesse gestartet werden..* in Regex. Da dies die Ausführung jedes Befehls nach einer Pipe erlauben würde.var callbackFunction = function(violationEvent, violations, violationLimitPerMinReached) {
console.log(JSON.stringify(violationEvent, null, 4));
};
violationEvent – Aufgetretener RAP-Verstoß. Er wird als CSP-Verstoß dargestellt.
violations – Anzahl der RAP-Verstöße. Wird jede Minute auf NULL zurückgesetzt.
violationLimitPerMinReached – true, wenn die Anzahl der RAP-Verstöße 'maxViolationsPerMinute' [eine Option in RAP] überschreitet.
Um einen Angriff zu blockieren – einen Fehler auslösen
throw new Error("Anfrage blockiert. Sie verstößt gegen die deklarierte Ressourcenzugriffsrichtlinie.")
{
"csp-report": {
"document-uri": "https://Unique-App-Id",
"blocked-uri": "https://compromised.domdog.io:443",
"violated-directive": "connect-src",
"effective-directive": "connect-src",
"original-policy": "{\"outBoundRequest\":{\"blockedDomains\":[\"compromised.domdog.io\"],\"allowedDomains\":[]}}",
"disposition": "report",
"status-code": 200,
"script-sample": "",
"source-file": "Error\n at TLSSocket.obj.<computed> [as connect] (/mnt/c/Ironwasp/Product/NodeSecurityShield/lib/hook.js:20:25)\n at Object.connect (_tls_wrap.js:1606:13)\n at Agent.createConnection (https.js:126:22)\n at Agent.createSocket (_http_agent.js:273:26)\n at Agent.addRequest (_http_agent.js:232:10)\n at new ClientRequest (_http_client.js:302:16)\n at request (https.js:310:10)\n at Object.get (https.js:314:15)\n at /mnt/c/Ironwasp/RD/Node/SimpleVulnerableNode/routes/ssrf.js:19:19\n at Layer.handle [as handle_request] (/mnt/c/Ironwasp/RD/Node/SimpleVulnerableNode/node_modules/express/lib/router/layer.js:95:5)"
}
}
document-uri: enthält die Unique-App-Id, die bei der Initialisierung von NSS übergeben wurdeblocked-uri: Domain der ausgehenden Anfrage, die gegen RAP verstoßen hatviolated-directive: connect-src ist ein Synonym für ausgehende Anfrage, ebenso ist script-src ein Synonym für Befehlsausführungoriginal-policy: die verletzte Ressourcenzugriffsrichtlinie (RAP)source-file: Stack-Trace des Verstoßesconst resourceAccessPolicy = {
"outBoundRequest": {
"blockedDomains": ["compromised.domdog.io"],
"allowedDomains": []
},
"executedCommand": {
"allowedCommands": ["pwd", "(node)[](https://github.com/domdogsec/nodesecurityshield/blob/HEAD/helper%5C/)[a-z|0-9]*(.js)"]
},
"reportUri": "https://ingest.sentry.io/api/6011856/security/?sentry_key=",
};
outBoundRequest: definiert das akzeptierte Verhalten für ausgehende Anfragen
executedCommand: definiert das akzeptierte Verhalten für Befehlsausführung
allowedCommands-Array akzeptiert String. Sie können einen Regex übergeben, um ein Muster von Befehlen zuzulassen.executedCommand definiert hat.pwd zur Ausführung erlaubt und.js-Dateien innerhalb von helper als Node-Prozesse gestartet werden..* in Regex. Da dies die Ausführung jedes Befehls nach einer Pipe erlauben würde.Screenshot aus dem Sentry-Dashboard

const resourceAccessPolicy = {
"outBoundRequest": {
"blockedDomains": ["compromised.domdog.io"],
"allowedDomains": ["domdog.io","*.domdog.io",
{
"domains": [
"domgo.at",
],
"modules": [
{
"file": "\/routes\/ssrf.js",
},
{
"file": "\/node_modules\/axios\/",
}
]
},
{
"domains": [
"cluster0-shard-00-00.lb9jm.mongodb.net",
"cluster0-shard-00-01.lb9jm.mongodb.net",
"cluster0-shard-00-02.lb9jm.mongodb.net"
],
"modules": [
{
"file": "\/node_modules\/mongodb\/"
}
]
}
]
},
"executedCommand": {
"allowedCommands": ["pwd", "(node)[](https://github.com/domdogsec/nodesecurityshield/blob/HEAD/helper%5C/)[a-z|0-9]*(.js)"]
},
"reportUri": "https://endpoint-to-send-violations",
"maxViolationsPerMinute": 50
}
outBoundRequest: definiert das akzeptierte Verhalten für ausgehende Anfragen
executedCommand: definiert das akzeptierte Verhalten für Befehlsausführung
allowedCommands-Array akzeptiert String. Sie können einen Regex übergeben, um ein Muster von Befehlen zuzulassen.executedCommand definiert hat.pwd zur Ausführung erlaubt und.js-Dateien innerhalb von helper als Node-Prozesse gestartet werden..* in Regex. Da dies die Ausführung jedes Befehls nach einer Pipe erlauben würde.||reportUri : Sendet Verstöße an einen bestimmten Endpunkt. Da Verstöße ähnlich wie Content Security Policy-Verstöße sind, können alle CSP-Überwachungslösungen verwendet werden. Wir haben in der obigen RAP den Sentry-Endpunkt verwendet.|reportUri: Sendet Verstöße an einen bestimmten Endpunkt. Da Verstöße ähnlich wie Content Security Policy-Verstöße sind, können alle CSP-Überwachungslösungen verwendet werden. Wir haben in der obigen RAP den Sentry-Endpunkt verwendet.allowedDomain-Array akzeptiert Objekte mit folgendem Inhalt:
domain: Array von Domains, die für die angegebenen Dateien erlaubt sind.modules: Array von Objekten mit Dateipfaden. Nur ausgehende Anfragen, die durch diese Dateien an die angegebenen Domains gestellt werden, sind erlaubt.maxViolationsPerMinute: Maximale Anzahl von Verstößen, die an die reportUri gesendet werden.
Wenn nicht angegeben, wird der Standardwert (100 Verstöße) verwendet.