JS: add query js/disabling-certificate-validation

This commit is contained in:
Esben Sparre Andreasen
2020-06-11 12:25:59 +02:00
parent 8b3dd6dec4
commit 2e059376fd
5 changed files with 142 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
</overview>
<recommendation>
</recommendation>
<example>
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,40 @@
/**
* @name Disabling certificate validation
* @description Disabling cryptographic certificate validation can cause security vulnerabilities.
* @kind problem
* @problem.severity error
* @precision very-high
* @id js/disabling-certificate-validation
* @tags security
* external/cwe-295
*/
import javascript
from DataFlow::PropWrite disable
where
exists(DataFlow::SourceNode env |
env = NodeJSLib::process().getAPropertyRead("env") and
disable = env.getAPropertyWrite("NODE_TLS_REJECT_UNAUTHORIZED") and
disable.getRhs().mayHaveStringValue("0")
)
or
exists(DataFlow::ObjectLiteralNode options, DataFlow::InvokeNode invk |
options.flowsTo(invk.getAnArgument()) and
disable = options.getAPropertyWrite("rejectUnauthorized") and
disable.getRhs().(AnalyzedNode).getTheBooleanValue() = false
|
invk instanceof NodeJSLib::NodeJSClientRequest
or
invk = DataFlow::moduleMember("https", "Agent").getAnInstantiation()
or
exists(DataFlow::NewNode new |
new = DataFlow::moduleMember("tls", "TLSSocket").getAnInstantiation()
|
invk = new or
invk = new.getAMethodCall("renegotiate")
)
or
invk = DataFlow::moduleMember("tls", ["connect", "createServer"]).getACall()
)
select disable, "Disabling certificate validation is strongly discouraged."

View File

@@ -0,0 +1,9 @@
| tst.js:15:3:15:27 | rejectU ... : false | Disabling certificate validation is strongly discouraged. |
| tst.js:18:1:18:40 | process ... HORIZED | Disabling certificate validation is strongly discouraged. |
| tst.js:21:3:21:27 | rejectU ... : false | Disabling certificate validation is strongly discouraged. |
| tst.js:25:3:25:27 | rejectU ... : false | Disabling certificate validation is strongly discouraged. |
| tst.js:29:3:29:27 | rejectU ... : false | Disabling certificate validation is strongly discouraged. |
| tst.js:34:3:34:27 | rejectU ... : false | Disabling certificate validation is strongly discouraged. |
| tst.js:39:2:39:29 | rejectU ... ndirect | Disabling certificate validation is strongly discouraged. |
| tst.js:45:2:45:28 | rejectU ... !!false | Disabling certificate validation is strongly discouraged. |
| tst.js:48:2:48:26 | rejectU ... : !true | Disabling certificate validation is strongly discouraged. |

View File

@@ -0,0 +1 @@
Security/CWE-295/DisablingCertificateValidation.ql

View File

@@ -0,0 +1,70 @@
let https = require("https"),
tls = require("tls");
new https.Agent(); // OK
new https.Agent({
rejectUnauthorized: true // OK
});
unknownCall({
rejectUnauthorized: false // OK (but probably unsafe after all)
});
new https.Agent({
rejectUnauthorized: false // NOT OK
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; // NOT OK
https.get({
rejectUnauthorized: false // NOT OK
});
new tls.TLSSocket(socket, {
rejectUnauthorized: false // NOT OK
});
tls.connect({
rejectUnauthorized: false // NOT OK
});
let socket = new tls.TLSSocket();
socket.renegotiate({
rejectUnauthorized: false // NOT OK
});
let indirect = false;
new https.Agent({
rejectUnauthorized: indirect // NOT OK
});
new https.Agent({
rejectUnauthorized: !false // OK
});
new https.Agent({
rejectUnauthorized: !!false // NOT OK
});
new https.Agent({
rejectUnauthorized: !true // NOT OK
});
new https.Agent({
rejectUnauthorized: !!true // OK
});
new https.Agent({
rejectUnauthorized: unknown() // OK
});
new https.Agent({
rejectUnauthorized: !getOptions().selfSignedSSL // OK
});
new https.Agent({
rejectUnauthorized: getOptions().rejectUnauthorized // OK
});
new https.Agent({
rejectUnauthorized: !!getOptions().rejectUnauthorized // OK
});
new https.Agent({
rejectUnauthorized: getOptions() == null ? true : getOptions().verifySsl // OK
});
new https.Agent({
rejectUnauthorized: typeof getOptions().rejectUnauthorized === 'boolean' ? getOptions().rejectUnauthorized : undefined // OK
});