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; + +import DisabledCertificateCheckExtensionFlow::PathGraph + +from + DisabledCertificateCheckExtensionFlow::PathNode sourceNode, + DisabledCertificateCheckExtensionFlow::PathNode sinkNode +where DisabledCertificateCheckExtensionFlow::flowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, "Disabling TLS certificate validation can expose the application to man-in-the-middle attacks." diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index 7cd4fd67e24b..e62f8ca9c5b5 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -22,6 +22,7 @@ private import codeql.rust.security.AccessInvalidPointerExtensions private import codeql.rust.security.CleartextLoggingExtensions private import codeql.rust.security.CleartextStorageDatabaseExtensions private import codeql.rust.security.CleartextTransmissionExtensions +private import codeql.rust.security.DisabledCertificateCheckExtensions private import codeql.rust.security.HardcodedCryptographicValueExtensions private import codeql.rust.security.InsecureCookieExtensions private import codeql.rust.security.LogInjectionExtensions 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 113f41731c43..e060b50494dd 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,42 @@ -| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | -| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +#select +| main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +| main.rs:93:32:93:47 | sometimes_global | main.rs:106:17:106:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. | +edges +| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | | +| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | | +| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | | +| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | | +| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | | +| main.rs:106:17:106:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | | +nodes +| main.rs:4:32:4:35 | true | semmle.label | true | +| main.rs:9:36:9:39 | true | semmle.label | true | +| main.rs:16:32:16:35 | true | semmle.label | true | +| main.rs:17:36:17:39 | true | semmle.label | true | +| main.rs:37:32:37:35 | true | semmle.label | true | +| main.rs:42:36:42:39 | true | semmle.label | true | +| main.rs:47:32:47:35 | true | semmle.label | true | +| main.rs:48:36:48:39 | true | semmle.label | true | +| main.rs:55:32:55:35 | true | semmle.label | true | +| main.rs:56:36:56:39 | true | semmle.label | true | +| main.rs:73:19:73:40 | ...: bool | semmle.label | ...: bool | +| main.rs:74:6:74:11 | always | semmle.label | always | +| main.rs:74:15:74:18 | true | semmle.label | true | +| main.rs:75:6:75:18 | mut sometimes | semmle.label | mut sometimes | +| main.rs:75:22:75:25 | true | semmle.label | true | +| main.rs:83:32:83:37 | always | semmle.label | always | +| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes | +| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global | +| main.rs:106:17:106:20 | true | semmle.label | true | +subpaths 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 9c603c45c434..02bd61976e5f 100644 --- a/rust/ql/test/query-tests/security/CWE-295/main.rs +++ b/rust/ql/test/query-tests/security/CWE-295/main.rs @@ -71,8 +71,8 @@ fn test_reqwest() { } fn test_data_flow(sometimes_global: bool) { - let always = true; - let mut sometimes = true; + let always = true; // $ Source=always + let mut sometimes = true; // $ Source=sometimes let never = false; if rand::random_range(0 .. 2) == 0 { @@ -80,17 +80,17 @@ fn test_data_flow(sometimes_global: bool) { } let _client = native_tls::TlsConnector::builder() - .danger_accept_invalid_certs(always) // $ MISSING: Alert[rust/disabled-certificate-check] + .danger_accept_invalid_certs(always) // $ Alert[rust/disabled-certificate-check]=always .build() .unwrap(); let _client = native_tls::TlsConnector::builder() - .danger_accept_invalid_certs(sometimes) // $ MISSING: Alert[rust/disabled-certificate-check] + .danger_accept_invalid_certs(sometimes) // $ Alert[rust/disabled-certificate-check]=sometimes .build() .unwrap(); let _client = native_tls::TlsConnector::builder() - .danger_accept_invalid_certs(sometimes_global) // $ MISSING: Alert[rust/disabled-certificate-check] + .danger_accept_invalid_certs(sometimes_global) // $ Alert[rust/disabled-certificate-check]=arg .build() .unwrap(); @@ -103,6 +103,6 @@ fn test_data_flow(sometimes_global: bool) { fn main() { test_native_tls(); test_reqwest(); - test_data_flow(true); + test_data_flow(true); // $ Source=arg test_data_flow(false); } From bb78fdf1509458a8ef2aaffec75e14644b46f0b0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:50:50 +0000 Subject: [PATCH 05/28] Rust: Add qhelp and examples (translated from Go, by Copilot). --- .../CWE-295/DisabledCertificateCheck.qhelp | 39 +++++++++++++++++++ .../CWE-295/DisabledCertificateCheckBad.rs | 13 +++++++ .../CWE-295/DisabledCertificateCheckGood.rs | 18 +++++++++ 3 files changed, 70 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp create mode 100644 rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs create mode 100644 rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp new file mode 100644 index 000000000000..f00a5295f367 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp @@ -0,0 +1,39 @@ + + + + +

+In Rust, 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 and 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 tests or controlled environments. In production, always ensure certificate and hostname verification are enabled to prevent security risks. +

+
+ + +

+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: +

+ +
+ +
  • +Rust native-tls crate: TlsConnectorBuilder. +
  • +
  • +Rust reqwest crate: ClientBuilder. +
  • +
  • +Mozilla: Web Security Guidelines: HTTPS. +
  • +
    +
    diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs new file mode 100644 index 000000000000..67546a8a2ab1 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs @@ -0,0 +1,13 @@ +// 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() + .unwrap(); diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs new file mode 100644 index 000000000000..525d7e985490 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs @@ -0,0 +1,18 @@ +// 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 + .build() + .unwrap(); + +// Or simply use the default builder (safe) +let _client = native_tls::TlsConnector::builder() + .build() + .unwrap(); From 87d66c69a363784d5358e33578dae33a2e7e4168 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:10:02 +0000 Subject: [PATCH 06/28] Rust: Clean up the .qhelp a little. --- .../queries/security/CWE-295/DisabledCertificateCheck.qhelp | 6 +++--- 1 file 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 f00a5295f367..25eb25af6431 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 @@

    -In Rust, 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 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.

    -Do not set 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.

    @@ -21,7 +21,7 @@ The following code snippet shows a function that creates a TLS or HTTP client wi

    -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:

    From dcae0ef9750fc3c44e0fd5606c470ad348da82a1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:10:44 +0000 Subject: [PATCH 07/28] Rust: I prefer the original certificates reference from the Go .qhelp. --- .../src/queries/security/CWE-295/DisabledCertificateCheck.qhelp | 2 +- 1 file changed, 1 insertion(+), 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 25eb25af6431..c100c01786aa 100644 --- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp +++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp @@ -33,7 +33,7 @@ Rust native-tls crate: ClientBuilder.
  • -Mozilla: Web Security Guidelines: HTTPS. +SSL.com: Browsers and Certificate Validation.
  • From 49063ac8a9072671dbdccc75bef4ccf464b29b11 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:13:02 +0000 Subject: [PATCH 08/28] Rust: Cut down the example for readability. --- .../security/CWE-295/DisabledCertificateCheck.qhelp | 4 ++-- .../security/CWE-295/DisabledCertificateCheckBad.rs | 7 ------- .../security/CWE-295/DisabledCertificateCheckGood.rs | 12 ++---------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp index c100c01786aa..dfb0c1f4db10 100644 --- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp +++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp @@ -17,11 +17,11 @@ Do not set 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) ) }