From f6b7aeaaca57ea933b34be1735d259c1e6dc7d94 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 16:01:10 +0000
Subject: [PATCH 01/28] Rust: Add prototype query.
---
.../CWE-295/DisabledCertificateCheck.ql | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
new file mode 100644
index 000000000000..65b1d85f2168
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -0,0 +1,22 @@
+/**
+ * @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
+ * @problem.severity warning
+ * @security-severity 7.5
+ * @precision high
+ * @id rust/disabled-certificate-check
+ * @tags security
+ * external/cwe/cwe-295
+ */
+
+import rust
+
+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,
+ "Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks." // TODO: proper message.
From f8ef48b9244b0e2ac06111d7e122a1692d85313a Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 16:22:40 +0000
Subject: [PATCH 02/28] Rust: Add query test.
---
.../query-tests/security/CWE-295/Cargo.lock | 1596 +++++++++++++++++
.../CWE-295/DisabledCertificateCheck.expected | 10 +
.../CWE-295/DisabledCertificateCheck.qlref | 4 +
.../test/query-tests/security/CWE-295/main.rs | 108 ++
.../query-tests/security/CWE-295/options.yml | 5 +
5 files changed, 1723 insertions(+)
create mode 100644 rust/ql/test/query-tests/security/CWE-295/Cargo.lock
create mode 100644 rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
create mode 100644 rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
create mode 100644 rust/ql/test/query-tests/security/CWE-295/main.rs
create mode 100644 rust/ql/test/query-tests/security/CWE-295/options.yml
diff --git a/rust/ql/test/query-tests/security/CWE-295/Cargo.lock b/rust/ql/test/query-tests/security/CWE-295/Cargo.lock
new file mode 100644
index 000000000000..43943439edda
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/Cargo.lock
@@ -0,0 +1,1596 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "bitflags"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+
+[[package]]
+name = "bumpalo"
+version = "3.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[package]]
+name = "cc"
+version = "1.2.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
+]
+
+[[package]]
+name = "h2"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
+
+[[package]]
+name = "http"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+
+[[package]]
+name = "hyper"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1744436df46f0bde35af3eda22aeaba453aada65d8f1c171cd8a5f59030bd69f"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "itoa",
+ "pin-project-lite",
+ "pin-utils",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.27.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
+dependencies = [
+ "http",
+ "hyper",
+ "hyper-util",
+ "rustls",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
+dependencies = [
+ "bytes",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
+dependencies = [
+ "base64",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "ipnet",
+ "libc",
+ "percent-encoding",
+ "pin-project-lite",
+ "socket2",
+ "system-configuration",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "windows-registry",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
+dependencies = [
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
+
+[[package]]
+name = "icu_properties"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99"
+dependencies = [
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899"
+
+[[package]]
+name = "icu_provider"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "idna"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+
+[[package]]
+name = "iri-string"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "js-sys"
+version = "0.3.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.177"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+
+[[package]]
+name = "litemap"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
+
+[[package]]
+name = "log"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+
+[[package]]
+name = "memchr"
+version = "2.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "mio"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
+dependencies = [
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "openssl"
+version = "0.10.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.111"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "rand"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+dependencies = [
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+dependencies = [
+ "getrandom 0.3.4",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.12.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-rustls",
+ "hyper-tls",
+ "hyper-util",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tokio-native-tls",
+ "tower",
+ "tower-http",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "ring"
+version = "0.17.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom 0.2.16",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
+dependencies = [
+ "once_cell",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.103.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[package]]
+name = "schannel"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.145"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "slab"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "socket2"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
+dependencies = [
+ "libc",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "2.0.110"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
+dependencies = [
+ "fastrand",
+ "getrandom 0.3.4",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "test"
+version = "0.0.1"
+dependencies = [
+ "native-tls",
+ "rand",
+ "reqwest",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tokio"
+version = "1.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+dependencies = [
+ "bytes",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "socket2",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tower"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project-lite",
+ "sync_wrapper",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "iri-string",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
+[[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "url"
+version = "2.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasip2"
+version = "1.0.1+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "once_cell",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-registry"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
+dependencies = [
+ "windows-link 0.1.3",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link 0.2.1",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
+[[package]]
+name = "wit-bindgen"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+
+[[package]]
+name = "writeable"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
+
+[[package]]
+name = "yoke"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
+dependencies = [
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+
+[[package]]
+name = "zerotrie"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
new file mode 100644
index 000000000000..5c10ff873161
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -0,0 +1,10 @@
+| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
new file mode 100644
index 000000000000..cc99c2b151c9
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
@@ -0,0 +1,4 @@
+query: queries/security/CWE-295/DisabledCertificateCheck.ql
+postprocess:
+ - utils/test/PrettyPrintModels.ql
+ - utils/test/InlineExpectationsTestQuery.ql
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
new file mode 100644
index 000000000000..9c603c45c434
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -0,0 +1,108 @@
+fn test_native_tls() {
+ // unsafe
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .min_protocol_version(Some(native_tls::Protocol::Tlsv12))
+ .use_sni(true)
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ // safe
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(false) // good
+ .danger_accept_invalid_hostnames(false) // good
+ .build()
+ .unwrap();
+
+ // default (safe)
+ let _client = native_tls::TlsConnector::builder()
+ .build()
+ .unwrap();
+}
+
+fn test_reqwest() {
+ // unsafe
+ let _client = reqwest::Client::builder()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::blocking::ClientBuilder::new()
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::ClientBuilder::new()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::blocking::Client::builder()
+ .tcp_keepalive(std::time::Duration::from_secs(30))
+ .https_only(true)
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ // safe
+ let _client = reqwest::blocking::Client::builder()
+ .danger_accept_invalid_certs(false) // good
+ .danger_accept_invalid_hostnames(false) // good
+ .build()
+ .unwrap();
+
+ // default (safe)
+ let _client = reqwest::blocking::Client::builder()
+ .build()
+ .unwrap();
+}
+
+fn test_data_flow(sometimes_global: bool) {
+ let always = true;
+ let mut sometimes = true;
+ let never = false;
+
+ if rand::random_range(0 .. 2) == 0 {
+ sometimes = false;
+ }
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(always) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(sometimes) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(sometimes_global) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(never) // good
+ .build()
+ .unwrap();
+}
+
+fn main() {
+ test_native_tls();
+ test_reqwest();
+ test_data_flow(true);
+ test_data_flow(false);
+}
diff --git a/rust/ql/test/query-tests/security/CWE-295/options.yml b/rust/ql/test/query-tests/security/CWE-295/options.yml
new file mode 100644
index 000000000000..711dfe71f8bf
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/options.yml
@@ -0,0 +1,5 @@
+qltest_cargo_check: true
+qltest_dependencies:
+ - reqwest = { version = "0.12.9", features = ["blocking"] }
+ - native-tls = { version = "0.2.14" }
+ - rand = { version = "0.9.2" }
From 209f394b5effa32d9c740f64ed58a25cbf6a2ad7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 18:10:32 +0000
Subject: [PATCH 03/28] Rust: Fix the alert message.
---
.../CWE-295/DisabledCertificateCheck.ql | 10 +++++-----
.../CWE-295/DisabledCertificateCheck.expected | 20 +++++++++----------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 65b1d85f2168..9a8ee245e2c1 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -15,8 +15,8 @@ import rust
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,
- "Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks." // TODO: proper message.
+ fc.getStaticTarget().(Function).getName().getText() =
+ ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
+select fc,
+ "Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 5c10ff873161..113f41731c43 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,10 +1,10 @@
-| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| 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. |
From c77eef39e2806273ea6a3b66eaad36e085caf847 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 17:55:29 +0000
Subject: [PATCH 04/28] Rust: Convert the query to a path-problem with global
data flow.
---
.../DisabledCertificateCheckExtensions.qll | 42 +++++++++++++++
.../CWE-295/DisabledCertificateCheck.ql | 34 +++++++++---
rust/ql/src/queries/summary/Stats.qll | 1 +
.../CWE-295/DisabledCertificateCheck.expected | 52 +++++++++++++++----
.../test/query-tests/security/CWE-295/main.rs | 12 ++---
5 files changed, 118 insertions(+), 23 deletions(-)
create mode 100644 rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
new file mode 100644
index 000000000000..984dc0f1de13
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -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") }
+ }
+}
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 9a8ee245e2c1..0e5f8daea613 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -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
+In Rust, the
+Do not set
+The following code snippet shows a function that creates a TLS or HTTP client with certificate verification disabled:
+
+While this may be acceptable in a test, it should not be used in production code. Instead, always configure clients to verify certificates and hostnames:
+
-In Rust, the
-Do not set danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate and any host name, making it susceptible to man-in-the-middle attacks.
+danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in tests or controlled environments. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate and any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in tests or controlled environments. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
-While this may be acceptable in a test, it should not be used in production code. Instead, always configure clients to verify certificates and hostnames: +In production code, always configure clients to verify certificates and hostnames:
danger_accept_invalid_certs or danger_accept_inval
-The following code snippet shows a function that creates a TLS or HTTP client with certificate verification disabled:
+The following code snippet shows a function that creates an HTTP client with certificate verification disabled:
-In production code, always configure clients to verify certificates and hostnames:
+In production code, always configure clients to verify certificates:
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
index 67546a8a2ab1..9e4102c64ccb 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
@@ -1,12 +1,5 @@
// BAD: Disabling certificate validation in Rust
-// Using native_tls
-let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_certs(true) // disables certificate validation
- .build()
- .unwrap();
-
-// Using reqwest
let _client = reqwest::Client::builder()
.danger_accept_invalid_certs(true) // disables certificate validation
.build()
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
index 525d7e985490..c726a756c380 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
@@ -1,18 +1,10 @@
// GOOD: Certificate validation is enabled (default)
-// Using native_tls
-let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_certs(false) // certificate validation enabled
- .build()
- .unwrap();
-
-// Using reqwest
let _client = reqwest::Client::builder()
- .danger_accept_invalid_certs(false) // certificate validation enabled
+ .danger_accept_invalid_certs(false) // certificate validation enabled explicitly
.build()
.unwrap();
-// Or simply use the default builder (safe)
-let _client = native_tls::TlsConnector::builder()
+let _client = native_tls::TlsConnector::builder() // certificate validation enabled by default
.build()
.unwrap();
From 7a62642ed7a4561ffe3182a1c65aeb132536ab3f Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 12 Nov 2025 18:17:12 +0000
Subject: [PATCH 09/28] Rust: Change note.
---
.../src/change-notes/2025-11-12-disabled-certificate-check.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
diff --git a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
new file mode 100644
index 000000000000..43211d9c5e00
--- /dev/null
+++ b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
@@ -0,0 +1,4 @@
+---
+category: newQuery
+---
+* Added a new query `rust/disabled-certificate-check, to detect disabled TLS certificate checks.
From 0675a29ae690f88b7be87b3203c94e05a3c64ddf Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 12 Nov 2025 19:26:45 +0000
Subject: [PATCH 10/28] Rust: Minor corrections.
---
.../security/DisabledCertificateCheckExtensions.qll | 4 ++--
.../2025-11-12-disabled-certificate-check.md | 2 +-
.../security/CWE-295/DisabledCertificateCheck.qhelp | 2 +-
.../security/CWE-295/DisabledCertificateCheck.ql | 13 ++++++-------
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 984dc0f1de13..cfc988ae37f0 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -21,7 +21,7 @@ module DisabledCertificateCheckExtensions {
}
/**
- * A default sink for disabled certificate check based on function names.
+ * A default sink for disabled certificate check vulnerabilities based on function names.
*/
private class DefaultSink extends Sink {
DefaultSink() {
@@ -34,7 +34,7 @@ module DisabledCertificateCheckExtensions {
}
/**
- * A sink for disabled certificate check from model data.
+ * A sink for disabled certificate check vulnerabilities from model data.
*/
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
diff --git a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
index 43211d9c5e00..001102eb9d66 100644
--- a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
+++ b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
@@ -1,4 +1,4 @@
---
category: newQuery
---
-* Added a new query `rust/disabled-certificate-check, to detect disabled TLS certificate checks.
+* Added a new query `rust/disabled-certificate-check`, to detect disabled TLS certificate checks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index dfb0c1f4db10..4e9ce164f266 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -11,7 +11,7 @@ The danger_accept_invalid_certs and danger_accept_invalid_hos
-Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 0e5f8daea613..b054ec306f78 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -16,9 +16,9 @@ import codeql.rust.dataflow.DataFlow
import codeql.rust.security.DisabledCertificateCheckExtensions
/**
- * A taint configuration for disabling TLS certificate checks.
+ * A taint configuration for disabled TLS certificate checks.
*/
-module LogInjectionConfig implements DataFlow::ConfigSig {
+module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
import DisabledCertificateCheckExtensions
predicate isSource(DataFlow::Node node) {
@@ -30,13 +30,12 @@ module LogInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
}
-module DisabledCertificateCheckExtensionFlow = DataFlow::Global;
+module DisabledCertificateCheckFlow = DataFlow::Global;
-import DisabledCertificateCheckExtensionFlow::PathGraph
+import DisabledCertificateCheckFlow::PathGraph
from
- DisabledCertificateCheckExtensionFlow::PathNode sourceNode,
- DisabledCertificateCheckExtensionFlow::PathNode sinkNode
-where DisabledCertificateCheckExtensionFlow::flowPath(sourceNode, sinkNode)
+ DisabledCertificateCheckFlow::PathNode sourceNode, DisabledCertificateCheckFlow::PathNode sinkNode
+where DisabledCertificateCheckFlow::flowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode,
"Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."
From 42aca4a171c844c6e6c08c3c26c2a411e28e3dad Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 08:51:41 +0000
Subject: [PATCH 11/28] Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
---
.../queries/security/CWE-295/DisabledCertificateCheck.qhelp | 4 ++--
.../src/queries/security/CWE-295/DisabledCertificateCheck.ql | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index 4e9ce164f266..7284a7da407d 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -5,13 +5,13 @@
-The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification is performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
-Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification is enabled to prevent security risks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index b054ec306f78..d08ca32bb25e 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -1,6 +1,6 @@
/**
* @name Disabled TLS certificate check
- * @description If an application disables TLS certificate checking, it may be vulnerable to
+ * @description An application that disables TLS certificate checking is more vulnerable to
* man-in-the-middle attacks.
* @kind path-problem
* @problem.severity warning
From 15fa99a288dba86b8bca7919963505d66fbd4587 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 09:00:46 +0000
Subject: [PATCH 12/28] Rust: Clarify some confusing text in the .qhelp.
---
.../queries/security/CWE-295/DisabledCertificateCheck.qhelp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index 7284a7da407d..1824f6e78dfa 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -5,7 +5,10 @@
-The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification is performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs option on TLS connectors and HTTP clients controls whether certificate verification is performed. If this option is set to true, the client will accept any certificate, making it susceptible to man-in-the-middle attacks.
+
+
+Similarly, the danger_accept_invalid_hostnames option controls whether hostname verification is performed. If this option is set to true, the client will accept any valid certificate regardless of the site that certificate is for, again making it susceptible to man-in-the-middle attacks.
From 12cbb64ef849da634bc13cc076d40bb82f3416ba Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 08:38:07 +0000
Subject: [PATCH 13/28] Rust: Add query to suite .expected lists.
---
.../query-suite/rust-code-scanning.qls.expected | 1 +
.../query-suite/rust-security-and-quality.qls.expected | 1 +
.../query-suite/rust-security-extended.qls.expected | 1 +
3 files changed, 3 insertions(+)
diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
index 70e1bcb10647..ea26dc636648 100644
--- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
@@ -19,6 +19,7 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
ql/rust/ql/src/queries/security/CWE-918/RequestForgery.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
index 596fdef3b20e..815945745190 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
@@ -21,6 +21,7 @@ ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
index 102c63e7942b..3809a9fe01b1 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
@@ -20,6 +20,7 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
From e43000f7cf1c19c7b76307f97583d78855b5ac50 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 09:21:04 +0000
Subject: [PATCH 14/28] Rust: Correct ordering in query suite .expected lists.
---
.../query-suite/rust-code-scanning.qls.expected | 2 +-
.../query-suite/rust-security-and-quality.qls.expected | 2 +-
.../query-suite/rust-security-extended.qls.expected | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
index ea26dc636648..aa197cebd2e6 100644
--- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
@@ -11,6 +11,7 @@ ql/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql
ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -19,7 +20,6 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
ql/rust/ql/src/queries/security/CWE-918/RequestForgery.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
index 815945745190..301676965540 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -21,7 +22,6 @@ ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
index 3809a9fe01b1..ebbf95113875 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -20,7 +21,6 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
From 2da0814f652698096e9280beb7f1781fc7d623a7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 20 Nov 2025 19:15:33 +0000
Subject: [PATCH 15/28] Rust: Add test case involving taint.
---
.../CWE-295/DisabledCertificateCheck.expected | 12 +++--
.../test/query-tests/security/CWE-295/main.rs | 49 +++++++++++++++++++
2 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index e060b50494dd..87ca24ddd2f6 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -11,14 +11,17 @@
| 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. |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | 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 | |
+| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
+| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
+| main.rs:154:17:154: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 |
@@ -38,5 +41,8 @@ nodes
| 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 |
+| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
+| main.rs:144:39:144:42 | true | semmle.label | true |
+| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
+| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index 02bd61976e5f..f12f08580609 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -100,9 +100,58 @@ fn test_data_flow(sometimes_global: bool) {
.unwrap();
}
+fn test_threat_model_source() {
+ // hostname setting from `fs` functions returning `bool` directly
+ // (these are highly unnatural but serve to create simple tests)
+
+ let b1: bool = std::fs::exists("main.rs").unwrap();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b1) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b2) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ let b3 = std::fs::metadata("main.rs").unwrap().is_dir();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b3) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ // hostname setting from `stdin`, parsed to `bool`
+ // (these are a little closer to something real)
+
+ let mut input_line = String::new();
+ let input = std::io::stdin();
+ input.read_line(&mut input_line).unwrap();
+
+ let b4: bool = input_line.parse::().unwrap_or(false);
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b4) // $ MISSING: Alert[rust/disabled-certificate-check]=stdin
+ .build()
+ .unwrap();
+
+ let b5 = std::str::FromStr::from_str(&input_line).unwrap_or(false);
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b5) // $ MISSING: Alert[rust/disabled-certificate-check]=stdin
+ .build()
+ .unwrap();
+
+ let b6 = if (input_line == "true") { true } else { false }; // $ Source=true
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b6) // $ Alert[rust/disabled-certificate-check]=true
+ .build()
+ .unwrap();
+}
+
fn main() {
test_native_tls();
test_reqwest();
test_data_flow(true); // $ Source=arg
test_data_flow(false);
+ test_threat_model_source();
}
From 8145264b770b92daa2f55fd06145ecf86e7536ef Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 20 Nov 2025 19:01:16 +0000
Subject: [PATCH 16/28] Rust: Add threat model sources as additional sources
for the query.
---
.../src/queries/security/CWE-295/DisabledCertificateCheck.ql | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index d08ca32bb25e..487a2a009126 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -14,6 +14,7 @@
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.security.DisabledCertificateCheckExtensions
+import codeql.rust.Concepts
/**
* A taint configuration for disabled TLS certificate checks.
@@ -22,7 +23,11 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
import DisabledCertificateCheckExtensions
predicate isSource(DataFlow::Node node) {
+ // the constant `true`
node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
+ or
+ // a value controlled by a potential attacker
+ node instanceof ActiveThreatModelSource
}
predicate isSink(DataFlow::Node node) { node instanceof Sink }
From aca7877be23afde4c588d134064a162b9840aa95 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 13:42:22 +0000
Subject: [PATCH 17/28] Rust: Add some missing path / file metadata models.
---
.../rust/frameworks/stdlib/fs.model.yml | 22 +++++++++++++++++++
.../CWE-295/DisabledCertificateCheck.expected | 13 +++++++++++
.../test/query-tests/security/CWE-295/main.rs | 4 ++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
index 79b0b16f41e2..076cea745fb7 100644
--- a/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
@@ -3,14 +3,27 @@ extensions:
pack: codeql/rust-all
extensible: sourceModel
data:
+ - ["std::fs::exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read_to_string", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::path", "ReturnValue", "file", "manual"]
- ["::file_name", "ReturnValue", "file", "manual"]
- ["::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::open_buffered", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::exists", "ReturnValue", "file", "manual"]
+ - ["::try_exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::is_file", "ReturnValue", "file", "manual"]
+ - ["::is_dir", "ReturnValue", "file", "manual"]
+ - ["::is_symlink", "ReturnValue", "file", "manual"]
+ - ["::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sinkModel
@@ -68,3 +81,12 @@ extensions:
- ["::with_extension", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
- ["::with_file_name", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
- ["::with_file_name", "Argument[0]", "ReturnValue", "taint", "manual"]
+ - ["::accessed", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::created", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::file_type", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_file", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_dir", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_symlink", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::len", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::modified", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::permissions", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 87ca24ddd2f6..06773d55e08d 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -12,6 +12,7 @@
| 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:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | 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 | |
@@ -19,9 +20,16 @@ edges
| 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:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:1 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:2 |
+| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
+models
+| 1 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 2 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
@@ -41,6 +49,11 @@ nodes
| 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:107:6:107:7 | b1 | semmle.label | b1 |
+| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
+| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index f12f08580609..e62e0e4f4a2d 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -104,9 +104,9 @@ fn test_threat_model_source() {
// hostname setting from `fs` functions returning `bool` directly
// (these are highly unnatural but serve to create simple tests)
- let b1: bool = std::fs::exists("main.rs").unwrap();
+ let b1: bool = std::fs::exists("main.rs").unwrap(); // $ Source=exists
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b1) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b1) // $ Alert[rust/disabled-certificate-check]=exists
.build()
.unwrap();
From 89a9c4654764375abc284819818ad3a9ec2c9750 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:46:26 +0000
Subject: [PATCH 18/28] Rust: Second change note.
---
rust/ql/lib/change-notes/2025-11-21-fs.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 rust/ql/lib/change-notes/2025-11-21-fs.md
diff --git a/rust/ql/lib/change-notes/2025-11-21-fs.md b/rust/ql/lib/change-notes/2025-11-21-fs.md
new file mode 100644
index 000000000000..438acd94f9fd
--- /dev/null
+++ b/rust/ql/lib/change-notes/2025-11-21-fs.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added more detailed models for `std::fs` and `std::path`.
From 785754ec651c7e5c6af89e60b1e53e8587c25804 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:15:15 +0000
Subject: [PATCH 19/28] Rust: Switch the query to taint flow, since some taint
summaries are relevant now.
---
.../CWE-295/DisabledCertificateCheck.ql | 3 +-
.../CWE-295/DisabledCertificateCheck.expected | 36 ++++++++++++++++---
.../test/query-tests/security/CWE-295/main.rs | 8 ++---
3 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 487a2a009126..35b6d6e73241 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -13,6 +13,7 @@
import rust
import codeql.rust.dataflow.DataFlow
+import codeql.rust.dataflow.TaintTracking
import codeql.rust.security.DisabledCertificateCheckExtensions
import codeql.rust.Concepts
@@ -35,7 +36,7 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
}
-module DisabledCertificateCheckFlow = DataFlow::Global;
+module DisabledCertificateCheckFlow = TaintTracking::Global;
import DisabledCertificateCheckFlow::PathGraph
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 06773d55e08d..9d491193efdc 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -13,6 +13,8 @@
| 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:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | 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 | |
@@ -21,15 +23,29 @@ edges
| 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:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:1 |
-| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:2 |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:2 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:4 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
+| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:6 |
+| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
+| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:1 |
+| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
+| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:3 |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:5 |
+| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
models
-| 1 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 2 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 1 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 2 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 3 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 4 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 5 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
+| 6 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
@@ -54,6 +70,18 @@ nodes
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
+| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
+| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:113:11:113:71 | ... .is_file() | semmle.label | ... .is_file() |
+| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
+| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
+| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
+| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
+| main.rs:119:11:119:47 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
+| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index e62e0e4f4a2d..6088e6fc1bee 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -110,15 +110,15 @@ fn test_threat_model_source() {
.build()
.unwrap();
- let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file();
+ let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file(); // $ Source=is_file
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b2) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b2) // $ Alert[rust/disabled-certificate-check]=is_file
.build()
.unwrap();
- let b3 = std::fs::metadata("main.rs").unwrap().is_dir();
+ let b3 = std::fs::metadata("main.rs").unwrap().is_dir(); // $ Source=is_dir
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b3) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b3) // $ Alert[rust/disabled-certificate-check]=is_dir
.build()
.unwrap();
From ace7a77fd6b0a5d5107e86f6fa023b0a7bdfab67 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 16:01:59 +0000
Subject: [PATCH 20/28] Rust: Switch to MaD models.
---
.../rust/frameworks/native-tls.model.yml | 7 ++
.../codeql/rust/frameworks/reqwest.model.yml | 4 +
.../DisabledCertificateCheckExtensions.qll | 13 ---
.../CWE-295/DisabledCertificateCheck.expected | 102 ++++++++++++------
4 files changed, 82 insertions(+), 44 deletions(-)
create mode 100644 rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
new file mode 100644
index 000000000000..5af3245238a9
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
@@ -0,0 +1,7 @@
+extensions:
+ - addsTo:
+ pack: codeql/rust-all
+ extensible: sinkModel
+ data:
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
index 5457460919f2..e9bc66b4be75 100644
--- a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
@@ -11,6 +11,10 @@ extensions:
data:
- ["::request", "Argument[1]", "request-url", "manual"]
- ["::request", "Argument[1]", "request-url", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: summaryModel
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index cfc988ae37f0..08cf20670d6d 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -20,19 +20,6 @@ module DisabledCertificateCheckExtensions {
override string getSinkType() { result = "DisabledCertificateCheck" }
}
- /**
- * A default sink for disabled certificate check vulnerabilities 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 vulnerabilities from model data.
*/
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 9d491193efdc..bbc67f6fd18a 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,89 +1,129 @@
#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:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:16:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:37:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:47:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:55:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:83:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:88:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:93:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
+| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
+| main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
+| main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | provenance | MaD:3 Sink:MaD:3 |
+| main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
+| main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | provenance | MaD:3 Sink:MaD:3 |
+| main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | provenance | MaD:4 Sink:MaD:4 |
+| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
+| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| 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:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:2 |
-| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
+| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
-| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:4 |
-| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:6 |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
+| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
-| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:1 |
+| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
+| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
-| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:3 |
-| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:4 |
-| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:5 |
+| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
+| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
+| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
+| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
models
-| 1 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 2 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 3 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 4 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
-| 5 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
-| 6 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
+| 1 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 2 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 3 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 4 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 5 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 6 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 7 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 8 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 9 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 10 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 11 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
+| 12 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
nodes
+| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
+| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
+| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
+| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
+| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
+| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
+| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
+| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
+| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
+| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| 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:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
+| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
+| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:113:11:113:71 | ... .is_file() | semmle.label | ... .is_file() |
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
+| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
| main.rs:119:11:119:47 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
+| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
+| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From 3ad014b2f9c426efe062a99bef63bc666fb9d773 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 16:33:59 +0000
Subject: [PATCH 21/28] Rust: Additional sinks found in MRVA-1000.
---
.../ql/lib/codeql/rust/frameworks/attohttpc.model.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
new file mode 100644
index 000000000000..0015d605f196
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
@@ -0,0 +1,11 @@
+extensions:
+ - addsTo:
+ pack: codeql/rust-all
+ extensible: sinkModel
+ data:
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
From e01c871b70a8d0b58b1dcfcd0b11eed603dc27a4 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 17:12:23 +0000
Subject: [PATCH 22/28] Rust: Accept changes to the dataflow/sources/file test.
---
.../library-tests/dataflow/sources/file/TaintSources.expected | 2 ++
rust/ql/test/library-tests/dataflow/sources/file/test.rs | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
index d73106fb1cfd..f7687e025d78 100644
--- a/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
+++ b/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
@@ -4,8 +4,10 @@
| test.rs:17:31:17:38 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
+| test.rs:26:18:26:29 | ...::read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:29:22:29:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:43:27:43:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
+| test.rs:51:52:51:59 | read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:54:22:54:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:55:27:55:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:65:22:65:34 | ...::read_link | Flow source 'FileSource' of type file (DEFAULT). |
diff --git a/rust/ql/test/library-tests/dataflow/sources/file/test.rs b/rust/ql/test/library-tests/dataflow/sources/file/test.rs
index 35a7d2cc1b80..0124d2a094e0 100644
--- a/rust/ql/test/library-tests/dataflow/sources/file/test.rs
+++ b/rust/ql/test/library-tests/dataflow/sources/file/test.rs
@@ -23,7 +23,7 @@ fn test_fs() -> Result<(), Box> {
sink(buffer); // $ hasTaintFlow="file.txt"
}
- for entry in fs::read_dir("directory")? {
+ for entry in fs::read_dir("directory")? { // $ Alert[rust/summary/taint-sources]
let e = entry?;
let path = e.path(); // $ Alert[rust/summary/taint-sources]
@@ -48,7 +48,7 @@ fn test_fs() -> Result<(), Box> {
sink(file_name.clone().as_encoded_bytes()); // $ MISSING: hasTaintFlow
sink(file_name); // $ hasTaintFlow
}
- for entry in std::path::Path::new("directory").read_dir()? {
+ for entry in std::path::Path::new("directory").read_dir()? { // $ Alert[rust/summary/taint-sources]
let e = entry?;
let path = e.path(); // $ Alert[rust/summary/taint-sources]
From 2ce4c47646806910a684f747d3b59617a3b19631 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:43:35 +0000
Subject: [PATCH 23/28] Rust: More sinks from the MRVA-1000.
---
rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml | 2 ++
rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml | 2 ++
2 files changed, 4 insertions(+)
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
index 0015d605f196..47e1beb3925f 100644
--- a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
@@ -9,3 +9,5 @@ extensions:
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
index 5af3245238a9..1da63eb7961a 100644
--- a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
@@ -5,3 +5,5 @@ extensions:
data:
- ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
From eb674d08d63c48e9beb4f94e773cb5281b801540 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:45:47 +0000
Subject: [PATCH 24/28] Rust: Reinstate the original function names model but
call it a heuristic now.
---
.../lib/codeql/rust/frameworks/attohttpc.model.yml | 13 -------------
.../security/DisabledCertificateCheckExtensions.qll | 13 +++++++++++++
2 files changed, 13 insertions(+), 13 deletions(-)
delete mode 100644 rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
deleted file mode 100644
index 47e1beb3925f..000000000000
--- a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-extensions:
- - addsTo:
- pack: codeql/rust-all
- extensible: sinkModel
- data:
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 08cf20670d6d..67efbc5b5ad4 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -26,4 +26,17 @@ module DisabledCertificateCheckExtensions {
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
}
+
+ /**
+ * A heuristic sink for disabled certificate check vulnerabilities based on function names.
+ */
+ private class HeuristicSink extends Sink {
+ HeuristicSink() {
+ exists(CallExprBase fc |
+ fc.getStaticTarget().(Function).getName().getText() =
+ ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0) = this.asExpr()
+ )
+ }
+ }
}
From ff8032a4ec220ef1ca181cac68966eea6206ae09 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:53:57 +0000
Subject: [PATCH 25/28] Rust: Fix after merge.
---
.../ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 35b6d6e73241..ae22a3c9d2c0 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -25,7 +25,7 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
// the constant `true`
- node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
+ node.asExpr().(BooleanLiteralExpr).getTextValue() = "true"
or
// a value controlled by a potential attacker
node instanceof ActiveThreatModelSource
From 0ea28b402613611deb1e572b4c5e8526e1ab7e59 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:56:53 +0000
Subject: [PATCH 26/28] Rust: Test .expected changes.
---
.../CWE-295/DisabledCertificateCheck.expected | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index bbc67f6fd18a..d01cdfda84b2 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,21 +1,38 @@
#select
| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| 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:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | 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:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | 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:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | 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:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | 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:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | 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:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | 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:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | 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:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | 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:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | 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:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | 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:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | 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:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
@@ -28,31 +45,38 @@ edges
| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
+| 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: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: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:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
+| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
+| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
+| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
+| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
@@ -72,24 +96,34 @@ models
nodes
| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
+| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
+| main.rs:9:36:9:39 | true | semmle.label | true |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
+| main.rs:16:32:16:35 | true | semmle.label | true |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
+| main.rs:17:36:17:39 | true | semmle.label | true |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
+| main.rs:37:32:37:35 | true | semmle.label | true |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
+| main.rs:42:36:42:39 | true | semmle.label | true |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
+| main.rs:47:32:47:35 | true | semmle.label | true |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
+| main.rs:48:36:48:39 | true | semmle.label | true |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
+| main.rs:55:32:55:35 | true | semmle.label | true |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:56:36:56:39 | 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 |
@@ -97,16 +131,20 @@ nodes
| main.rs:75:22:75:25 | true | semmle.label | true |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
+| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
+| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
+| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
+| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
@@ -114,6 +152,7 @@ nodes
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
+| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
@@ -121,9 +160,11 @@ nodes
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
+| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
+| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From 993154ed57b46ff0db88348fe53b2b9baa4ada49 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 19:33:40 +0000
Subject: [PATCH 27/28] Rust: Avoid duplicating sinks.
---
.../DisabledCertificateCheckExtensions.qll | 5 ++-
.../CWE-295/DisabledCertificateCheck.expected | 41 -------------------
2 files changed, 4 insertions(+), 42 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 67efbc5b5ad4..e2870746547e 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -7,6 +7,7 @@ import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts
+private import codeql.rust.dataflow.internal.Node as Node
/**
* Provides default sinks for detecting disabled certificate check
@@ -35,7 +36,9 @@ module DisabledCertificateCheckExtensions {
exists(CallExprBase fc |
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
- fc.getArg(0) = this.asExpr()
+ fc.getArg(0) = this.asExpr() and
+ // don't duplicate modelled sinks
+ not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc)
)
}
}
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index d01cdfda84b2..bbc67f6fd18a 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,38 +1,21 @@
#select
| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| 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:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | 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:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | 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:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | 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:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | 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:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | 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:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | 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:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | 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:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | 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:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | 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:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | 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:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | 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:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
@@ -45,38 +28,31 @@ edges
| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
-| 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: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: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:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
-| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
-| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
-| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
@@ -96,34 +72,24 @@ models
nodes
| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
-| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
-| main.rs:9:36:9:39 | true | semmle.label | true |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
-| main.rs:16:32:16:35 | true | semmle.label | true |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
-| main.rs:17:36:17:39 | true | semmle.label | true |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
-| main.rs:37:32:37:35 | true | semmle.label | true |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
-| main.rs:42:36:42:39 | true | semmle.label | true |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
-| main.rs:47:32:47:35 | true | semmle.label | true |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
-| main.rs:48:36:48:39 | true | semmle.label | true |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
-| main.rs:55:32:55:35 | true | semmle.label | true |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:56:36:56:39 | 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 |
@@ -131,20 +97,16 @@ nodes
| main.rs:75:22:75:25 | true | semmle.label | true |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
-| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
-| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
-| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
-| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
@@ -152,7 +114,6 @@ nodes
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
-| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
@@ -160,11 +121,9 @@ nodes
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
-| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
-| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From b62968fa0ff8c4bbc04b0527cd1cc7ed6ba637ef Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Sat, 22 Nov 2025 09:22:33 +0000
Subject: [PATCH 28/28] Rust: Spelling.
---
.../codeql/rust/security/DisabledCertificateCheckExtensions.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index e2870746547e..6a885828ee98 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -37,7 +37,7 @@ module DisabledCertificateCheckExtensions {
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
fc.getArg(0) = this.asExpr() and
- // don't duplicate modelled sinks
+ // don't duplicate modeled sinks
not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc)
)
}