Rust: Convert the query to a path-problem with global data flow.

This commit is contained in:
Geoffrey White
2025-11-11 17:55:29 +00:00
parent 209f394b5e
commit c77eef39e2
5 changed files with 118 additions and 23 deletions

View File

@@ -0,0 +1,42 @@
/**
* Provides classes and predicates for reasoning about disabled certificate
* check vulnerabilities.
*/
import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts
/**
* Provides default sinks for detecting disabled certificate check
* vulnerabilities, as well as extension points for adding your own.
*/
module DisabledCertificateCheckExtensions {
/**
* A data flow sink for disabled certificate check vulnerabilities.
*/
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "DisabledCertificateCheck" }
}
/**
* A default sink for disabled certificate check based on function names.
*/
private class DefaultSink extends Sink {
DefaultSink() {
exists(CallExprBase fc |
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
fc.getArg(0) = this.asExpr().getExpr()
)
}
}
/**
* A sink for disabled certificate check from model data.
*/
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
}
}

View File

@@ -2,7 +2,7 @@
* @name Disabled TLS certificate check
* @description If an application disables TLS certificate checking, it may be vulnerable to
* man-in-the-middle attacks.
* @kind problem
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision high
@@ -12,11 +12,31 @@
*/
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.security.DisabledCertificateCheckExtensions
from CallExprBase fc
where
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
select fc,
/**
* A taint configuration for disabling TLS certificate checks.
*/
module LogInjectionConfig implements DataFlow::ConfigSig {
import DisabledCertificateCheckExtensions
predicate isSource(DataFlow::Node node) {
node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
}
predicate isSink(DataFlow::Node node) { node instanceof Sink }
predicate observeDiffInformedIncrementalMode() { any() }
}
module DisabledCertificateCheckExtensionFlow = DataFlow::Global<LogInjectionConfig>;
import DisabledCertificateCheckExtensionFlow::PathGraph
from
DisabledCertificateCheckExtensionFlow::PathNode sourceNode,
DisabledCertificateCheckExtensionFlow::PathNode sinkNode
where DisabledCertificateCheckExtensionFlow::flowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode,
"Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."

View File

@@ -22,6 +22,7 @@ private import codeql.rust.security.AccessInvalidPointerExtensions
private import codeql.rust.security.CleartextLoggingExtensions
private import codeql.rust.security.CleartextStorageDatabaseExtensions
private import codeql.rust.security.CleartextTransmissionExtensions
private import codeql.rust.security.DisabledCertificateCheckExtensions
private import codeql.rust.security.HardcodedCryptographicValueExtensions
private import codeql.rust.security.InsecureCookieExtensions
private import codeql.rust.security.LogInjectionExtensions

View File

@@ -1,10 +1,42 @@
| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
#select
| main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:93:32:93:47 | sometimes_global | main.rs:106:17:106:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
| main.rs:106:17:106:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
| main.rs:16:32:16:35 | true | semmle.label | true |
| main.rs:17:36:17:39 | true | semmle.label | true |
| main.rs:37:32:37:35 | true | semmle.label | true |
| main.rs:42:36:42:39 | true | semmle.label | true |
| main.rs:47:32:47:35 | true | semmle.label | true |
| main.rs:48:36:48:39 | true | semmle.label | true |
| main.rs:55:32:55:35 | true | semmle.label | true |
| main.rs:56:36:56:39 | true | semmle.label | true |
| main.rs:73:19:73:40 | ...: bool | semmle.label | ...: bool |
| main.rs:74:6:74:11 | always | semmle.label | always |
| main.rs:74:15:74:18 | true | semmle.label | true |
| main.rs:75:6:75:18 | mut sometimes | semmle.label | mut sometimes |
| main.rs:75:22:75:25 | true | semmle.label | true |
| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:106:17:106:20 | true | semmle.label | true |
subpaths

View File

@@ -71,8 +71,8 @@ fn test_reqwest() {
}
fn test_data_flow(sometimes_global: bool) {
let always = true;
let mut sometimes = true;
let always = true; // $ Source=always
let mut sometimes = true; // $ Source=sometimes
let never = false;
if rand::random_range(0 .. 2) == 0 {
@@ -80,17 +80,17 @@ fn test_data_flow(sometimes_global: bool) {
}
let _client = native_tls::TlsConnector::builder()
.danger_accept_invalid_certs(always) // $ MISSING: Alert[rust/disabled-certificate-check]
.danger_accept_invalid_certs(always) // $ Alert[rust/disabled-certificate-check]=always
.build()
.unwrap();
let _client = native_tls::TlsConnector::builder()
.danger_accept_invalid_certs(sometimes) // $ MISSING: Alert[rust/disabled-certificate-check]
.danger_accept_invalid_certs(sometimes) // $ Alert[rust/disabled-certificate-check]=sometimes
.build()
.unwrap();
let _client = native_tls::TlsConnector::builder()
.danger_accept_invalid_certs(sometimes_global) // $ MISSING: Alert[rust/disabled-certificate-check]
.danger_accept_invalid_certs(sometimes_global) // $ Alert[rust/disabled-certificate-check]=arg
.build()
.unwrap();
@@ -103,6 +103,6 @@ fn test_data_flow(sometimes_global: bool) {
fn main() {
test_native_tls();
test_reqwest();
test_data_flow(true);
test_data_flow(true); // $ Source=arg
test_data_flow(false);
}