From 513ae2ab54ec75a62d73d9912b156a4ed8282919 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:05:27 +0100 Subject: [PATCH 01/22] Rust: Add tests for insecure cookies. --- .../query-tests/security/CWE-614/Cargo.lock | 684 ++++++++++++++++++ .../test/query-tests/security/CWE-614/main.rs | 174 +++++ .../query-tests/security/CWE-614/options.yml | 4 + 3 files changed, 862 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-614/Cargo.lock create mode 100644 rust/ql/test/query-tests/security/CWE-614/main.rs create mode 100644 rust/ql/test/query-tests/security/CWE-614/options.yml diff --git a/rust/ql/test/query-tests/security/CWE-614/Cargo.lock b/rust/ql/test/query-tests/security/CWE-614/Cargo.lock new file mode 100644 index 000000000000..1d2124de710d --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/Cargo.lock @@ -0,0 +1,684 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "biscotti" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb6f28a3d15d18cace7a8010282a4d9cee1452dcd33f5861c173b4a31095b79" +dependencies = [ + "aes-gcm-siv", + "anyhow", + "base64", + "hkdf", + "hmac", + "jiff", + "percent-encoding", + "rand 0.9.2", + "serde", + "sha2", + "subtle", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "aes-gcm", + "base64", + "hmac", + "percent-encoding", + "rand 0.8.5", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "deranged" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.5+wasi-0.2.4", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[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.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +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.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[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 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[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.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test" +version = "0.0.1" +dependencies = [ + "biscotti", + "cookie", +] + +[[package]] +name = "time" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.5+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[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_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[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_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[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_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs new file mode 100644 index 000000000000..da11fa5e5bc7 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -0,0 +1,174 @@ +use cookie::{Cookie, CookieBuilder, CookieJar, Key}; + +fn test_cookie(sometimes: bool) { + let always = true; + let never = false; + + // secure set to false + let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + println!("cookie1 = '{}'", cookie1.to_string()); + + // secure set to true + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good + println!("cookie2 = '{}'", cookie2.to_string()); + + // secure left as default (which is `None`, equivalent here to `false`) + let cookie3 = Cookie::build(("name", "value")).build(); // $ MISSING: Alert[rust/insecure-cookie] + println!("cookie3 = '{}'", cookie3.to_string()); + + // secure setting varies (may be false) + Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + + // with data flow on the "secure" value + Cookie::build(("name", "value")).secure(always).build(); // good + Cookie::build(("name", "value")).secure(!always).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(never).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!never).build(); // good + Cookie::build(("name", "value")).secure(always && never).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always || never).build(); // good + + // with guards + if sometimes { + Cookie::build(("name", "value")).secure(sometimes).build(); // good + } else { + Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + } + + // variant uses (all insecure) + CookieBuilder::new("name", "value").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).path("/").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).permanent().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).removal().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).finish(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build("name").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(Cookie::build("name")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + + // edge cases + Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // good + + // mutable cookie + let mut jar = CookieJar::new(); + let mut a = Cookie::new("name", "value"); + jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + a.set_secure(true); + jar.add(a.clone()); // good + a.set_secure(false); + jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + + let key = Key::generate(); + let mut signed_jar = jar.signed_mut(&key); + let mut b = Cookie::named("name"); + signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + b.set_secure(sometimes); + signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + b.set_secure(true); + signed_jar.add(b.clone()); // good + + let mut private_jar = jar.private_mut(&key); + let mut c = Cookie::from("name"); + private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + if sometimes { + c.set_secure(true); + } + private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + c.set_secure(true); + private_jar.add(c.clone()); // good + + let mut d = Cookie::from("name"); + jar.add(d.clone()); // $ MISSING: Alert[rust/insecure-cookie] + if sometimes { + c.set_secure(true); + } else { + c.set_partitioned(true); + } + jar.add(d.clone()); // good + + // parse + jar.add(Cookie::parse("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(Cookie::parse("name=value; Secure; HttpOnly").unwrap()); // good + jar.add(Cookie::parse_encoded("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(Cookie::parse_encoded("name=value; Secure; HttpOnly").unwrap()); // good + + for cookie in Cookie::split_parse("name1=value1; name2=value2") { + jar.add(cookie.unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + } + + for cookie in Cookie::split_parse_encoded("name1=value1; name2=value2") { + let mut e = cookie.unwrap(); + jar.add(e.clone()); // $ MISSING: Alert[rust/insecure-cookie] + e.set_secure(true); + jar.add(e.clone()); // good + } + + // partitioned (implies secure) + Cookie::build(("name", "value")).partitioned(true).build(); // good +} + +fn test_biscotti() { + let mut cookies = biscotti::ResponseCookies::new(); + + // test set_secure, set_partitioned + + let a = biscotti::ResponseCookie::new("name", "value"); + cookies.insert(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti1 = {}", a.to_string()); + + let b = a.set_secure(true); + cookies.insert(b.clone()); // good (secure) + println!("biscotti2 = {}", b.to_string()); + + let c = b.set_secure(false); + cookies.insert(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti3 = {}", c.to_string()); + + let d = c.set_partitioned(true); // (implies secure) + cookies.insert(d.clone()); // good (partitioned) + println!("biscotti4 = {}", d.to_string()); + + let e = d.set_secure(true); + cookies.insert(e.clone()); // good (partitioned + secure) + println!("biscotti5 = {}", e.to_string()); + + let f = e.set_partitioned(false); + cookies.insert(f.clone()); // good (secure) + println!("biscotti6 = {}", f.to_string()); + + let g = f.set_secure(false); + cookies.insert(g.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti7 = {}", g.to_string()); + + // variant creation (insecure) + let h = biscotti::ResponseCookie::from(("name", "value")); + cookies.insert(h); // $ MISSING: Alert[rust/insecure-cookie] + + // variant uses (all insecure) + let i = biscotti::ResponseCookie::new("name", "value"); + cookies.insert(i.clone().set_name("name2")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_value("value2")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_http_only(true)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_max_age(None)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_path("/")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_path()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_domain("example.com")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_domain()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_expires(None)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_expires()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().make_permanent()); // $ MISSING: Alert[rust/insecure-cookie] +} + +fn main() { + test_cookie(true); + test_cookie(false); + test_biscotti(); +} diff --git a/rust/ql/test/query-tests/security/CWE-614/options.yml b/rust/ql/test/query-tests/security/CWE-614/options.yml new file mode 100644 index 000000000000..99b8e37e8439 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/options.yml @@ -0,0 +1,4 @@ +qltest_cargo_check: true +qltest_dependencies: + - cookie = { version = "0.18.1", features = ["percent-encode", "signed", "private"] } + - biscotti = { version = "0.4.3" } From 7e75c1d24257c340e2ff8030c516c4820f5b254d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:17:05 +0100 Subject: [PATCH 02/22] Rust: Add very basic query prototype. --- .../security/CWE-614/InsecureCookie.ql | 48 +++++++++++++++++++ .../security/CWE-614/InsecureCookie.expected | 6 +++ .../security/CWE-614/InsecureCookie.qlref | 4 ++ .../test/query-tests/security/CWE-614/main.rs | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookie.ql create mode 100644 rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected create mode 100644 rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql new file mode 100644 index 000000000000..4d659d95a954 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -0,0 +1,48 @@ +/** + * @name 'Secure' attribute is not set to true + * @description Omitting the 'Secure' attribute allows data to be transmitted insecurely + * using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS + * is used at all times. + * @kind problem + * @problem.severity error + * @precision high + * @id rust/insecure-cookie + * @tags security + * external/cwe/cwe-319 + * external/cwe/cwe-614 + */ + +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.dataflow.TaintTracking +import InsecureCookieFlow::PathGraph + +/** + * A data flow configuration for tracking values representing cookies without the + * 'secure' flag set. + */ +module InsecureCookieConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + // creation of a cookie with default settings (insecure) + exists(CallExprBase ce | + ce.getStaticTarget().getCanonicalPath() = "::build" and + node.asExpr().getExpr() = ce + ) + } + + predicate isSink(DataFlow::Node node) { + // qualifier of a call to `.build`. + exists(MethodCallExpr ce | + ce.getStaticTarget().getCanonicalPath() = "::build" and + node.asExpr().getExpr() = ce.getReceiver() + ) + } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +module InsecureCookieFlow = TaintTracking::Global; + +from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode +where InsecureCookieFlow::flowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected new file mode 100644 index 000000000000..2f900fc34dc8 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -0,0 +1,6 @@ +#select +| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | Cookie attribute 'Secure' is not set to true. | +edges +nodes +| main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | +subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref new file mode 100644 index 000000000000..36a9751434ce --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref @@ -0,0 +1,4 @@ +query: queries/security/CWE-614/InsecureCookie.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index da11fa5e5bc7..6ef4cc3c83b7 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -13,7 +13,7 @@ fn test_cookie(sometimes: bool) { println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) - let cookie3 = Cookie::build(("name", "value")).build(); // $ MISSING: Alert[rust/insecure-cookie] + let cookie3 = Cookie::build(("name", "value")).build(); // $ Alert[rust/insecure-cookie] println!("cookie3 = '{}'", cookie3.to_string()); // secure setting varies (may be false) From d52b6681497071cb89cd27378a884f6ecc33cb87 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:22:46 +0100 Subject: [PATCH 03/22] Rust: Add security-severity tag. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 4d659d95a954..f14af7752fd9 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -5,6 +5,7 @@ * is used at all times. * @kind problem * @problem.severity error + * @security-severity 7.5 * @precision high * @id rust/insecure-cookie * @tags security From eadf922280a7ddf7004fccf9802b1d07d66f8bae Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 15 Sep 2025 09:24:16 +0100 Subject: [PATCH 04/22] Rust: Use models-as-data, add source/sink/flow models. --- .../codeql/rust/frameworks/biscotti.model.yml | 25 + .../codeql/rust/frameworks/cookie.model.yml | 33 + .../security/CWE-614/InsecureCookie.ql | 19 +- .../security/CWE-614/InsecureCookie.expected | 636 +++++++++++++++++- .../test/query-tests/security/CWE-614/main.rs | 122 ++-- 5 files changed, 762 insertions(+), 73 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml index c99a2433348a..b70a27f74d16 100644 --- a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml @@ -1,7 +1,32 @@ # Models for the `biscotti` crate. extensions: + - addsTo: + pack: codeql/rust-all + extensible: sourceModel + data: + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::from", "ReturnValue", "cookie-create", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel data: + - ["::insert", "Argument[0]", "cookie-use", "manual"] - ["::from", "Argument[0]", "credentials-key", "manual"] + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_name", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_value", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_http_only", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_same_site", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_max_age", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::make_permanent", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml index abbadd379e6e..f9c8cd647c56 100644 --- a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml @@ -1,7 +1,40 @@ # Models for the `cookie` crate. extensions: + - addsTo: + pack: codeql/rust-all + extensible: sourceModel + data: + - ["::build", "ReturnValue", "cookie-create", "manual"] + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::named", "ReturnValue", "cookie-create", "manual"] + - ["::from", "ReturnValue", "cookie-create", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel data: + - ["::build", "Argument[self]", "cookie-use", "manual"] + - ["::finish", "Argument[self]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] - ["::from", "Argument[0].Reference", "credentials-key", "manual"] + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["::secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::max_age", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::http_only", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::same_site", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::permanent", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::removal", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index f14af7752fd9..69d11b85bef3 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -16,7 +16,8 @@ import rust import codeql.rust.dataflow.DataFlow import codeql.rust.dataflow.TaintTracking -import InsecureCookieFlow::PathGraph +import codeql.rust.dataflow.FlowSource +import codeql.rust.dataflow.FlowSink /** * A data flow configuration for tracking values representing cookies without the @@ -24,19 +25,13 @@ import InsecureCookieFlow::PathGraph */ module InsecureCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { - // creation of a cookie with default settings (insecure) - exists(CallExprBase ce | - ce.getStaticTarget().getCanonicalPath() = "::build" and - node.asExpr().getExpr() = ce - ) + // creation of a cookie or cookie configuration with default, insecure settings + sourceNode(node, "cookie-create") } predicate isSink(DataFlow::Node node) { - // qualifier of a call to `.build`. - exists(MethodCallExpr ce | - ce.getStaticTarget().getCanonicalPath() = "::build" and - node.asExpr().getExpr() = ce.getReceiver() - ) + // use of a cookie or cookie configuration + sinkNode(node, "cookie-use") } predicate observeDiffInformedIncrementalMode() { any() } @@ -44,6 +39,8 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { module InsecureCookieFlow = TaintTracking::Global; +import InsecureCookieFlow::PathGraph + from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode where InsecureCookieFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 2f900fc34dc8..b4bd897ca6ff 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,6 +1,640 @@ #select -| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:12:65:12:69 | build | main.rs:12:19:12:31 | ...::build | main.rs:12:65:12:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:17 | ...::build | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:54:65:54:69 | build | main.rs:54:5:54:17 | ...::build | main.rs:54:65:54:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:69:16:69:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:69:16:69:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:74:16:74:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:74:16:74:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:78:17:78:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:78:17:78:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:83:17:83:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:83:17:83:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:114:56:114:60 | build | main.rs:114:5:114:17 | ...::build | main.rs:114:56:114:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:127:13:127:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:127:13:127:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:135:13:135:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:135:13:135:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:139:13:139:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:139:13:139:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:143:13:143:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:143:13:143:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:158:13:158:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:158:13:158:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:159:13:159:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:159:13:159:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:160:13:160:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:160:13:160:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:161:13:161:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:161:13:161:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:162:13:162:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:162:13:162:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:163:13:163:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:163:13:163:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:164:13:164:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:164:13:164:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:165:13:165:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:165:13:165:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:166:13:166:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:166:13:166:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges +| main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:12:19:12:31 | ...::build | main.rs:12:19:12:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:12:19:12:50 | ...::build(...) | main.rs:12:19:12:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:12:19:12:63 | ... .secure(...) | main.rs:12:65:12:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | +| main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | +| main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | +| main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | +| main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | +| main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | +| main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | +| main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | +| main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | +| main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | +| main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:53:5:53:17 | ...::build | main.rs:53:5:53:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:53:5:53:36 | ...::build(...) | main.rs:53:5:53:49 | ... .secure(...) | provenance | MaD:41 | +| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:54:5:54:17 | ...::build | main.rs:54:5:54:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:54:5:54:36 | ...::build(...) | main.rs:54:5:54:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:54:5:54:50 | ... .secure(...) | main.rs:54:5:54:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:54:5:54:63 | ... .secure(...) | main.rs:54:65:54:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:58:17:58:27 | ...::new | main.rs:58:17:58:44 | ...::new(...) | provenance | Src:MaD:15 MaD:15 | +| main.rs:58:17:58:44 | ...::new(...) | main.rs:58:9:58:13 | mut a | provenance | | +| main.rs:59:13:59:13 | a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | +| main.rs:59:13:59:21 | a.clone() | main.rs:59:9:59:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:60:22:60:22 | a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | +| main.rs:60:22:60:30 | a.clone() | main.rs:60:9:60:20 | add_original | provenance | MaD:5 Sink:MaD:5 | +| main.rs:62:13:62:13 | a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | +| main.rs:62:13:62:21 | a.clone() | main.rs:62:9:62:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:64:13:64:13 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:64:13:64:21 | a.clone() | main.rs:64:9:64:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:68:9:68:13 | mut b | main.rs:69:20:69:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:9:68:13 | mut b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:17:68:29 | ...::named | main.rs:68:17:68:37 | ...::named(...) | provenance | Src:MaD:14 MaD:14 | +| main.rs:68:17:68:37 | ...::named(...) | main.rs:68:9:68:13 | mut b | provenance | | +| main.rs:69:20:69:20 | b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | +| main.rs:69:20:69:28 | b.clone() | main.rs:69:16:69:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:70:29:70:29 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:70:29:70:37 | a.clone() | main.rs:70:16:70:27 | add_original | provenance | MaD:9 Sink:MaD:9 | +| main.rs:72:20:72:20 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:72:20:72:28 | b.clone() | main.rs:72:16:72:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:74:20:74:20 | b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | +| main.rs:74:20:74:28 | b.clone() | main.rs:74:16:74:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:77:9:77:13 | mut c | main.rs:78:21:78:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:9:77:13 | mut c | main.rs:83:21:83:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:17:77:28 | ...::from | main.rs:77:17:77:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | +| main.rs:77:17:77:36 | ...::from(...) | main.rs:77:9:77:13 | mut c | provenance | | +| main.rs:78:21:78:21 | c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | +| main.rs:78:21:78:29 | c.clone() | main.rs:78:17:78:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:79:30:79:30 | a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:79:30:79:38 | a.clone() | main.rs:79:17:79:28 | add_original | provenance | MaD:7 Sink:MaD:7 | +| main.rs:83:21:83:21 | c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | +| main.rs:83:21:83:29 | c.clone() | main.rs:83:17:83:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:85:21:85:21 | c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | +| main.rs:85:21:85:29 | c.clone() | main.rs:85:17:85:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:87:9:87:13 | mut d | main.rs:88:13:88:13 | d | provenance | | +| main.rs:87:9:87:13 | mut d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | +| main.rs:87:9:87:13 | mut d | main.rs:94:13:94:13 | d | provenance | | +| main.rs:87:9:87:13 | mut d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | +| main.rs:87:17:87:28 | ...::from | main.rs:87:17:87:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | +| main.rs:87:17:87:36 | ...::from(...) | main.rs:87:9:87:13 | mut d | provenance | | +| main.rs:88:13:88:13 | d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | +| main.rs:88:13:88:21 | d.clone() | main.rs:88:9:88:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | +| main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | +| main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | +| main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | +| main.rs:122:9:122:9 | a | main.rs:126:13:126:30 | a.set_secure(...) | provenance | MaD:27 | +| main.rs:122:13:122:41 | ...::new | main.rs:122:13:122:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | +| main.rs:122:13:122:58 | ...::new(...) | main.rs:122:9:122:9 | a | provenance | | +| main.rs:123:20:123:20 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | +| main.rs:123:20:123:28 | a.clone() | main.rs:123:13:123:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:126:9:126:9 | b | main.rs:127:20:127:20 | b | provenance | | +| main.rs:126:9:126:9 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | +| main.rs:126:9:126:9 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | +| main.rs:126:13:126:30 | a.set_secure(...) | main.rs:126:9:126:9 | b | provenance | | +| main.rs:127:20:127:20 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | +| main.rs:127:20:127:28 | b.clone() | main.rs:127:13:127:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | +| main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | +| main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | +| main.rs:130:13:130:31 | b.set_secure(...) | main.rs:130:9:130:9 | c | provenance | | +| main.rs:131:20:131:20 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | +| main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:134:9:134:9 | d | main.rs:135:20:135:20 | d | provenance | | +| main.rs:134:9:134:9 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | +| main.rs:134:9:134:9 | d | main.rs:138:13:138:30 | d.set_secure(...) | provenance | MaD:27 | +| main.rs:134:13:134:35 | c.set_partitioned(...) | main.rs:134:9:134:9 | d | provenance | | +| main.rs:135:20:135:20 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | +| main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:138:9:138:9 | e | main.rs:139:20:139:20 | e | provenance | | +| main.rs:138:9:138:9 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | +| main.rs:138:9:138:9 | e | main.rs:142:13:142:36 | e.set_partitioned(...) | provenance | MaD:24 | +| main.rs:138:13:138:30 | d.set_secure(...) | main.rs:138:9:138:9 | e | provenance | | +| main.rs:139:20:139:20 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | +| main.rs:139:20:139:28 | e.clone() | main.rs:139:13:139:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:142:9:142:9 | f | main.rs:143:20:143:20 | f | provenance | | +| main.rs:142:9:142:9 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | +| main.rs:142:9:142:9 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | +| main.rs:142:13:142:36 | e.set_partitioned(...) | main.rs:142:9:142:9 | f | provenance | | +| main.rs:143:20:143:20 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | +| main.rs:143:20:143:28 | f.clone() | main.rs:143:13:143:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | +| main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | +| main.rs:147:20:147:20 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:147:20:147:28 | g.clone() | main.rs:147:13:147:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:151:9:151:9 | h | main.rs:152:20:152:20 | h | provenance | | +| main.rs:151:13:151:42 | ...::from | main.rs:151:13:151:61 | ...::from(...) | provenance | Src:MaD:10 MaD:10 | +| main.rs:151:13:151:61 | ...::from(...) | main.rs:151:9:151:9 | h | provenance | | +| main.rs:152:20:152:20 | h | main.rs:152:13:152:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:155:9:155:9 | i | main.rs:156:20:156:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:156:20:156:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:157:20:157:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:158:20:158:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:159:20:159:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:159:20:159:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:160:20:160:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:160:20:160:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:161:20:161:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:161:20:161:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:162:20:162:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:163:20:163:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:164:20:164:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:165:20:165:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:166:20:166:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:167:20:167:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:13:155:41 | ...::new | main.rs:155:13:155:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | +| main.rs:155:13:155:58 | ...::new(...) | main.rs:155:9:155:9 | i | provenance | | +| main.rs:156:20:156:20 | i | main.rs:156:20:156:28 | i.clone() | provenance | MaD:17 | +| main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | +| main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | +| main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | +| main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | +| main.rs:158:20:158:48 | ... .set_http_only(...) | main.rs:158:13:158:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:159:20:159:20 | i | main.rs:159:20:159:28 | i.clone() | provenance | MaD:17 | +| main.rs:159:20:159:28 | i.clone() | main.rs:159:20:159:70 | ... .set_same_site(...) | provenance | MaD:26 | +| main.rs:159:20:159:70 | ... .set_same_site(...) | main.rs:159:13:159:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:160:20:160:20 | i | main.rs:160:20:160:28 | i.clone() | provenance | MaD:17 | +| main.rs:160:20:160:28 | i.clone() | main.rs:160:20:160:46 | ... .set_max_age(...) | provenance | MaD:22 | +| main.rs:160:20:160:46 | ... .set_max_age(...) | main.rs:160:13:160:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:161:20:161:20 | i | main.rs:161:20:161:28 | i.clone() | provenance | MaD:17 | +| main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | +| main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | +| main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | +| main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | +| main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | +| main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | +| main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | +| main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | +| main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | +| main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | +| main.rs:167:20:167:45 | ... .make_permanent() | main.rs:167:13:167:18 | insert | provenance | MaD:1 Sink:MaD:1 | +models +| 1 | Sink: ::insert; Argument[0]; cookie-use | +| 2 | Sink: ::build; Argument[self]; cookie-use | +| 3 | Sink: ::finish; Argument[self]; cookie-use | +| 4 | Sink: ::add; Argument[0]; cookie-use | +| 5 | Sink: ::add_original; Argument[0]; cookie-use | +| 6 | Sink: ::add; Argument[0]; cookie-use | +| 7 | Sink: ::add_original; Argument[0]; cookie-use | +| 8 | Sink: ::add; Argument[0]; cookie-use | +| 9 | Sink: ::add_original; Argument[0]; cookie-use | +| 10 | Source: ::from; ReturnValue; cookie-create | +| 11 | Source: ::new; ReturnValue; cookie-create | +| 12 | Source: ::from; ReturnValue; cookie-create | +| 13 | Source: ::build; ReturnValue; cookie-create | +| 14 | Source: ::named; ReturnValue; cookie-create | +| 15 | Source: ::new; ReturnValue; cookie-create | +| 16 | Source: ::new; ReturnValue; cookie-create | +| 17 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | +| 18 | Summary: ::make_permanent; Argument[self]; ReturnValue; taint | +| 19 | Summary: ::set_domain; Argument[self]; ReturnValue; taint | +| 20 | Summary: ::set_expires; Argument[self]; ReturnValue; taint | +| 21 | Summary: ::set_http_only; Argument[self]; ReturnValue; taint | +| 22 | Summary: ::set_max_age; Argument[self]; ReturnValue; taint | +| 23 | Summary: ::set_name; Argument[self]; ReturnValue; taint | +| 24 | Summary: ::set_partitioned; Argument[self]; ReturnValue; taint | +| 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | +| 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | +| 27 | Summary: ::set_secure; Argument[self]; ReturnValue; taint | +| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 36 | Summary: ::partitioned; Argument[self]; ReturnValue; taint | +| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 41 | Summary: ::secure; Argument[self]; ReturnValue; taint | nodes +| main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | +| main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:8:19:8:64 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:8:66:8:70 | build | semmle.label | build | +| main.rs:12:19:12:31 | ...::build | semmle.label | ...::build | +| main.rs:12:19:12:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:12:19:12:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:12:65:12:69 | build | semmle.label | build | +| main.rs:16:19:16:31 | ...::build | semmle.label | ...::build | | main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:16:52:16:56 | build | semmle.label | build | +| main.rs:20:5:20:17 | ...::build | semmle.label | ...::build | +| main.rs:20:5:20:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:20:5:20:54 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:20:56:20:60 | build | semmle.label | build | +| main.rs:21:5:21:17 | ...::build | semmle.label | ...::build | +| main.rs:21:5:21:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:21:5:21:55 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:21:57:21:61 | build | semmle.label | build | +| main.rs:24:5:24:17 | ...::build | semmle.label | ...::build | +| main.rs:24:5:24:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:24:5:24:51 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:24:53:24:57 | build | semmle.label | build | +| main.rs:25:5:25:17 | ...::build | semmle.label | ...::build | +| main.rs:25:5:25:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:25:5:25:52 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:25:54:25:58 | build | semmle.label | build | +| main.rs:26:5:26:17 | ...::build | semmle.label | ...::build | +| main.rs:26:5:26:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:26:5:26:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:26:52:26:56 | build | semmle.label | build | +| main.rs:27:5:27:17 | ...::build | semmle.label | ...::build | +| main.rs:27:5:27:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:27:5:27:51 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:27:53:27:57 | build | semmle.label | build | +| main.rs:28:5:28:17 | ...::build | semmle.label | ...::build | +| main.rs:28:5:28:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:28:5:28:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:28:62:28:66 | build | semmle.label | build | +| main.rs:29:5:29:17 | ...::build | semmle.label | ...::build | +| main.rs:29:5:29:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:29:5:29:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:29:62:29:66 | build | semmle.label | build | +| main.rs:33:9:33:21 | ...::build | semmle.label | ...::build | +| main.rs:33:9:33:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:33:9:33:58 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:33:60:33:64 | build | semmle.label | build | +| main.rs:35:9:35:21 | ...::build | semmle.label | ...::build | +| main.rs:35:9:35:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:35:9:35:58 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:35:60:35:64 | build | semmle.label | build | +| main.rs:39:5:39:22 | ...::new | semmle.label | ...::new | +| main.rs:39:5:39:39 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:39:5:39:53 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:39:55:39:59 | build | semmle.label | build | +| main.rs:40:5:40:17 | ...::build | semmle.label | ...::build | +| main.rs:40:5:40:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:40:5:40:50 | ... .expires(...) | semmle.label | ... .expires(...) | +| main.rs:40:5:40:64 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:40:66:40:70 | build | semmle.label | build | +| main.rs:41:5:41:17 | ...::build | semmle.label | ...::build | +| main.rs:41:5:41:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:41:5:41:79 | ... .max_age(...) | semmle.label | ... .max_age(...) | +| main.rs:41:5:41:93 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:41:95:41:99 | build | semmle.label | build | +| main.rs:42:5:42:17 | ...::build | semmle.label | ...::build | +| main.rs:42:5:42:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:42:5:42:58 | ... .domain(...) | semmle.label | ... .domain(...) | +| main.rs:42:5:42:72 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:42:74:42:78 | build | semmle.label | build | +| main.rs:43:5:43:17 | ...::build | semmle.label | ...::build | +| main.rs:43:5:43:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:43:5:43:46 | ... .path(...) | semmle.label | ... .path(...) | +| main.rs:43:5:43:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:43:62:43:66 | build | semmle.label | build | +| main.rs:44:5:44:17 | ...::build | semmle.label | ...::build | +| main.rs:44:5:44:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:44:5:44:52 | ... .http_only(...) | semmle.label | ... .http_only(...) | +| main.rs:44:5:44:66 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:44:68:44:72 | build | semmle.label | build | +| main.rs:45:5:45:17 | ...::build | semmle.label | ...::build | +| main.rs:45:5:45:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:45:5:45:72 | ... .same_site(...) | semmle.label | ... .same_site(...) | +| main.rs:45:5:45:86 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:45:88:45:92 | build | semmle.label | build | +| main.rs:46:5:46:17 | ...::build | semmle.label | ...::build | +| main.rs:46:5:46:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:46:5:46:48 | ... .permanent() | semmle.label | ... .permanent() | +| main.rs:46:5:46:62 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:46:64:46:68 | build | semmle.label | build | +| main.rs:47:5:47:17 | ...::build | semmle.label | ...::build | +| main.rs:47:5:47:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:47:5:47:46 | ... .removal() | semmle.label | ... .removal() | +| main.rs:47:5:47:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:47:62:47:66 | build | semmle.label | build | +| main.rs:48:5:48:17 | ...::build | semmle.label | ...::build | +| main.rs:48:5:48:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:48:5:48:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:48:52:48:57 | finish | semmle.label | finish | +| main.rs:49:5:49:17 | ...::build | semmle.label | ...::build | +| main.rs:49:5:49:25 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:49:5:49:39 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:49:41:49:45 | build | semmle.label | build | +| main.rs:50:5:50:17 | ...::build | semmle.label | ...::build | +| main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:50:56:50:60 | build | semmle.label | build | +| main.rs:53:5:53:17 | ...::build | semmle.label | ...::build | +| main.rs:53:5:53:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:53:65:53:69 | build | semmle.label | build | +| main.rs:54:5:54:17 | ...::build | semmle.label | ...::build | +| main.rs:54:5:54:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:54:5:54:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:54:5:54:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:54:65:54:69 | build | semmle.label | build | +| main.rs:58:9:58:13 | mut a | semmle.label | mut a | +| main.rs:58:17:58:27 | ...::new | semmle.label | ...::new | +| main.rs:58:17:58:44 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:59:9:59:11 | add | semmle.label | add | +| main.rs:59:13:59:13 | a | semmle.label | a | +| main.rs:59:13:59:21 | a.clone() | semmle.label | a.clone() | +| main.rs:60:9:60:20 | add_original | semmle.label | add_original | +| main.rs:60:22:60:22 | a | semmle.label | a | +| main.rs:60:22:60:30 | a.clone() | semmle.label | a.clone() | +| main.rs:62:9:62:11 | add | semmle.label | add | +| main.rs:62:13:62:13 | a | semmle.label | a | +| main.rs:62:13:62:21 | a.clone() | semmle.label | a.clone() | +| main.rs:64:9:64:11 | add | semmle.label | add | +| main.rs:64:13:64:13 | a | semmle.label | a | +| main.rs:64:13:64:21 | a.clone() | semmle.label | a.clone() | +| main.rs:68:9:68:13 | mut b | semmle.label | mut b | +| main.rs:68:17:68:29 | ...::named | semmle.label | ...::named | +| main.rs:68:17:68:37 | ...::named(...) | semmle.label | ...::named(...) | +| main.rs:69:16:69:18 | add | semmle.label | add | +| main.rs:69:20:69:20 | b | semmle.label | b | +| main.rs:69:20:69:28 | b.clone() | semmle.label | b.clone() | +| main.rs:70:16:70:27 | add_original | semmle.label | add_original | +| main.rs:70:29:70:29 | a | semmle.label | a | +| main.rs:70:29:70:37 | a.clone() | semmle.label | a.clone() | +| main.rs:72:16:72:18 | add | semmle.label | add | +| main.rs:72:20:72:20 | b | semmle.label | b | +| main.rs:72:20:72:28 | b.clone() | semmle.label | b.clone() | +| main.rs:74:16:74:18 | add | semmle.label | add | +| main.rs:74:20:74:20 | b | semmle.label | b | +| main.rs:74:20:74:28 | b.clone() | semmle.label | b.clone() | +| main.rs:77:9:77:13 | mut c | semmle.label | mut c | +| main.rs:77:17:77:28 | ...::from | semmle.label | ...::from | +| main.rs:77:17:77:36 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:78:17:78:19 | add | semmle.label | add | +| main.rs:78:21:78:21 | c | semmle.label | c | +| main.rs:78:21:78:29 | c.clone() | semmle.label | c.clone() | +| main.rs:79:17:79:28 | add_original | semmle.label | add_original | +| main.rs:79:30:79:30 | a | semmle.label | a | +| main.rs:79:30:79:38 | a.clone() | semmle.label | a.clone() | +| main.rs:83:17:83:19 | add | semmle.label | add | +| main.rs:83:21:83:21 | c | semmle.label | c | +| main.rs:83:21:83:29 | c.clone() | semmle.label | c.clone() | +| main.rs:85:17:85:19 | add | semmle.label | add | +| main.rs:85:21:85:21 | c | semmle.label | c | +| main.rs:85:21:85:29 | c.clone() | semmle.label | c.clone() | +| main.rs:87:9:87:13 | mut d | semmle.label | mut d | +| main.rs:87:17:87:28 | ...::from | semmle.label | ...::from | +| main.rs:87:17:87:36 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:88:9:88:11 | add | semmle.label | add | +| main.rs:88:13:88:13 | d | semmle.label | d | +| main.rs:88:13:88:21 | d.clone() | semmle.label | d.clone() | +| main.rs:94:9:94:11 | add | semmle.label | add | +| main.rs:94:13:94:13 | d | semmle.label | d | +| main.rs:94:13:94:21 | d.clone() | semmle.label | d.clone() | +| main.rs:114:5:114:17 | ...::build | semmle.label | ...::build | +| main.rs:114:5:114:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:114:5:114:54 | ... .partitioned(...) | semmle.label | ... .partitioned(...) | +| main.rs:114:56:114:60 | build | semmle.label | build | +| main.rs:122:9:122:9 | a | semmle.label | a | +| main.rs:122:13:122:41 | ...::new | semmle.label | ...::new | +| main.rs:122:13:122:58 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:123:13:123:18 | insert | semmle.label | insert | +| main.rs:123:20:123:20 | a | semmle.label | a | +| main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | +| main.rs:126:9:126:9 | b | semmle.label | b | +| main.rs:126:13:126:30 | a.set_secure(...) | semmle.label | a.set_secure(...) | +| main.rs:127:13:127:18 | insert | semmle.label | insert | +| main.rs:127:20:127:20 | b | semmle.label | b | +| main.rs:127:20:127:28 | b.clone() | semmle.label | b.clone() | +| main.rs:130:9:130:9 | c | semmle.label | c | +| main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | +| main.rs:131:13:131:18 | insert | semmle.label | insert | +| main.rs:131:20:131:20 | c | semmle.label | c | +| main.rs:131:20:131:28 | c.clone() | semmle.label | c.clone() | +| main.rs:134:9:134:9 | d | semmle.label | d | +| main.rs:134:13:134:35 | c.set_partitioned(...) | semmle.label | c.set_partitioned(...) | +| main.rs:135:13:135:18 | insert | semmle.label | insert | +| main.rs:135:20:135:20 | d | semmle.label | d | +| main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | +| main.rs:138:9:138:9 | e | semmle.label | e | +| main.rs:138:13:138:30 | d.set_secure(...) | semmle.label | d.set_secure(...) | +| main.rs:139:13:139:18 | insert | semmle.label | insert | +| main.rs:139:20:139:20 | e | semmle.label | e | +| main.rs:139:20:139:28 | e.clone() | semmle.label | e.clone() | +| main.rs:142:9:142:9 | f | semmle.label | f | +| main.rs:142:13:142:36 | e.set_partitioned(...) | semmle.label | e.set_partitioned(...) | +| main.rs:143:13:143:18 | insert | semmle.label | insert | +| main.rs:143:20:143:20 | f | semmle.label | f | +| main.rs:143:20:143:28 | f.clone() | semmle.label | f.clone() | +| main.rs:146:9:146:9 | g | semmle.label | g | +| main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | +| main.rs:147:13:147:18 | insert | semmle.label | insert | +| main.rs:147:20:147:20 | g | semmle.label | g | +| main.rs:147:20:147:28 | g.clone() | semmle.label | g.clone() | +| main.rs:151:9:151:9 | h | semmle.label | h | +| main.rs:151:13:151:42 | ...::from | semmle.label | ...::from | +| main.rs:151:13:151:61 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:152:13:152:18 | insert | semmle.label | insert | +| main.rs:152:20:152:20 | h | semmle.label | h | +| main.rs:155:9:155:9 | i | semmle.label | i | +| main.rs:155:13:155:41 | ...::new | semmle.label | ...::new | +| main.rs:155:13:155:58 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:156:13:156:18 | insert | semmle.label | insert | +| main.rs:156:20:156:20 | i | semmle.label | i | +| main.rs:156:20:156:28 | i.clone() | semmle.label | i.clone() | +| main.rs:156:20:156:46 | ... .set_name(...) | semmle.label | ... .set_name(...) | +| main.rs:157:13:157:18 | insert | semmle.label | insert | +| main.rs:157:20:157:20 | i | semmle.label | i | +| main.rs:157:20:157:28 | i.clone() | semmle.label | i.clone() | +| main.rs:157:20:157:48 | ... .set_value(...) | semmle.label | ... .set_value(...) | +| main.rs:158:13:158:18 | insert | semmle.label | insert | +| main.rs:158:20:158:20 | i | semmle.label | i | +| main.rs:158:20:158:28 | i.clone() | semmle.label | i.clone() | +| main.rs:158:20:158:48 | ... .set_http_only(...) | semmle.label | ... .set_http_only(...) | +| main.rs:159:13:159:18 | insert | semmle.label | insert | +| main.rs:159:20:159:20 | i | semmle.label | i | +| main.rs:159:20:159:28 | i.clone() | semmle.label | i.clone() | +| main.rs:159:20:159:70 | ... .set_same_site(...) | semmle.label | ... .set_same_site(...) | +| main.rs:160:13:160:18 | insert | semmle.label | insert | +| main.rs:160:20:160:20 | i | semmle.label | i | +| main.rs:160:20:160:28 | i.clone() | semmle.label | i.clone() | +| main.rs:160:20:160:46 | ... .set_max_age(...) | semmle.label | ... .set_max_age(...) | +| main.rs:161:13:161:18 | insert | semmle.label | insert | +| main.rs:161:20:161:20 | i | semmle.label | i | +| main.rs:161:20:161:28 | i.clone() | semmle.label | i.clone() | +| main.rs:161:20:161:42 | ... .set_path(...) | semmle.label | ... .set_path(...) | +| main.rs:162:13:162:18 | insert | semmle.label | insert | +| main.rs:162:20:162:20 | i | semmle.label | i | +| main.rs:162:20:162:28 | i.clone() | semmle.label | i.clone() | +| main.rs:162:20:162:41 | ... .unset_path() | semmle.label | ... .unset_path() | +| main.rs:163:13:163:18 | insert | semmle.label | insert | +| main.rs:163:20:163:20 | i | semmle.label | i | +| main.rs:163:20:163:28 | i.clone() | semmle.label | i.clone() | +| main.rs:163:20:163:54 | ... .set_domain(...) | semmle.label | ... .set_domain(...) | +| main.rs:164:13:164:18 | insert | semmle.label | insert | +| main.rs:164:20:164:20 | i | semmle.label | i | +| main.rs:164:20:164:28 | i.clone() | semmle.label | i.clone() | +| main.rs:164:20:164:43 | ... .unset_domain() | semmle.label | ... .unset_domain() | +| main.rs:165:13:165:18 | insert | semmle.label | insert | +| main.rs:165:20:165:20 | i | semmle.label | i | +| main.rs:165:20:165:28 | i.clone() | semmle.label | i.clone() | +| main.rs:165:20:165:46 | ... .set_expires(...) | semmle.label | ... .set_expires(...) | +| main.rs:166:13:166:18 | insert | semmle.label | insert | +| main.rs:166:20:166:20 | i | semmle.label | i | +| main.rs:166:20:166:28 | i.clone() | semmle.label | i.clone() | +| main.rs:166:20:166:44 | ... .unset_expires() | semmle.label | ... .unset_expires() | +| main.rs:167:13:167:18 | insert | semmle.label | insert | +| main.rs:167:20:167:20 | i | semmle.label | i | +| main.rs:167:20:167:28 | i.clone() | semmle.label | i.clone() | +| main.rs:167:20:167:45 | ... .make_permanent() | semmle.label | ... .make_permanent() | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 6ef4cc3c83b7..0f0f929fd147 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -5,11 +5,11 @@ fn test_cookie(sometimes: bool) { let never = false; // secure set to false - let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ Alert[rust/insecure-cookie] println!("cookie1 = '{}'", cookie1.to_string()); // secure set to true - let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) @@ -17,81 +17,81 @@ fn test_cookie(sometimes: bool) { println!("cookie3 = '{}'", cookie3.to_string()); // secure setting varies (may be false) - Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(!sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(sometimes).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!sometimes).build(); // $ Alert[rust/insecure-cookie] // with data flow on the "secure" value - Cookie::build(("name", "value")).secure(always).build(); // good - Cookie::build(("name", "value")).secure(!always).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(never).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(!never).build(); // good - Cookie::build(("name", "value")).secure(always && never).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(always || never).build(); // good + Cookie::build(("name", "value")).secure(always).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!always).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(never).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always && never).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always || never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] // with guards if sometimes { - Cookie::build(("name", "value")).secure(sometimes).build(); // good + Cookie::build(("name", "value")).secure(sometimes).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] } else { - Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(sometimes).build(); // $ Alert[rust/insecure-cookie] } // variant uses (all insecure) - CookieBuilder::new("name", "value").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).path("/").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).permanent().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).removal().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).finish(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build("name").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(Cookie::build("name")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + CookieBuilder::new("name", "value").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).path("/").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).permanent().secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).removal().secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).finish(); // $ Alert[rust/insecure-cookie] + Cookie::build("name").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(Cookie::build("name")).secure(false).build(); // $ Alert[rust/insecure-cookie] // edge cases - Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).secure(true).build(); // good + Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] // mutable cookie let mut jar = CookieJar::new(); let mut a = Cookie::new("name", "value"); - jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] - jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(a.clone()); // $ Alert[rust/insecure-cookie] + jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); - jar.add(a.clone()); // good + jar.add(a.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] a.set_secure(false); - jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(a.clone()); // $ Alert[rust/insecure-cookie] let key = Key::generate(); let mut signed_jar = jar.signed_mut(&key); let mut b = Cookie::named("name"); - signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] - signed_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] + signed_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(sometimes); - signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); - signed_jar.add(b.clone()); // good + signed_jar.add(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] let mut private_jar = jar.private_mut(&key); let mut c = Cookie::from("name"); - private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] - private_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] + private_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); } - private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] c.set_secure(true); - private_jar.add(c.clone()); // good + private_jar.add(c.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] let mut d = Cookie::from("name"); - jar.add(d.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(d.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); } else { c.set_partitioned(true); } - jar.add(d.clone()); // good + jar.add(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] // parse jar.add(Cookie::parse("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] @@ -111,7 +111,7 @@ fn test_cookie(sometimes: bool) { } // partitioned (implies secure) - Cookie::build(("name", "value")).partitioned(true).build(); // good + Cookie::build(("name", "value")).partitioned(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] } fn test_biscotti() { @@ -120,51 +120,51 @@ fn test_biscotti() { // test set_secure, set_partitioned let a = biscotti::ResponseCookie::new("name", "value"); - cookies.insert(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(a.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti1 = {}", a.to_string()); let b = a.set_secure(true); - cookies.insert(b.clone()); // good (secure) + cookies.insert(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti2 = {}", b.to_string()); let c = b.set_secure(false); - cookies.insert(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(c.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti3 = {}", c.to_string()); let d = c.set_partitioned(true); // (implies secure) - cookies.insert(d.clone()); // good (partitioned) + cookies.insert(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti4 = {}", d.to_string()); let e = d.set_secure(true); - cookies.insert(e.clone()); // good (partitioned + secure) + cookies.insert(e.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti5 = {}", e.to_string()); let f = e.set_partitioned(false); - cookies.insert(f.clone()); // good (secure) + cookies.insert(f.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti6 = {}", f.to_string()); let g = f.set_secure(false); - cookies.insert(g.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(g.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti7 = {}", g.to_string()); // variant creation (insecure) let h = biscotti::ResponseCookie::from(("name", "value")); - cookies.insert(h); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(h); // $ Alert[rust/insecure-cookie] // variant uses (all insecure) let i = biscotti::ResponseCookie::new("name", "value"); - cookies.insert(i.clone().set_name("name2")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_value("value2")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_http_only(true)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_max_age(None)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_path("/")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_path()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_domain("example.com")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_domain()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_expires(None)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_expires()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().make_permanent()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_name("name2")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_value("value2")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_http_only(true)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_max_age(None)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_path("/")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_path()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_domain("example.com")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_domain()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_expires(None)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_expires()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } fn main() { From 257a1b0179255d987a7cc5d4a9584ff9fcdd3376 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:55:45 +0100 Subject: [PATCH 05/22] Rust: Refactor sources, sinks into an extensions source file. --- .../security/InsecureCookieExtensions.qll | 49 +++++++++++++++++++ .../security/CWE-614/InsecureCookie.ql | 18 ++++--- rust/ql/src/queries/summary/Stats.qll | 5 +- 3 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll new file mode 100644 index 000000000000..47baa46440c7 --- /dev/null +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -0,0 +1,49 @@ +/** + * Provides classes and predicates for reasoning about insecure cookie + * vulnerabilities. + */ + +import rust +private import codeql.rust.dataflow.DataFlow +private import codeql.rust.dataflow.FlowSource +private import codeql.rust.dataflow.FlowSink +private import codeql.rust.Concepts +private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl +private import codeql.rust.dataflow.internal.Node + +/** + * Provides default sources, sinks and barriers for detecting insecure + * cookie vulnerabilities, as well as extension points for adding your own. + */ +module InsecureCookie { + /** + * A data flow source for insecure cookie vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for insecure cookie vulnerabilities. + */ + abstract class Sink extends QuerySink::Range { + override string getSinkType() { result = "InsecureCookie" } + } + + /** + * A barrier for insecure cookie vulnerabilities. + */ + abstract class Barrier extends DataFlow::Node { } + + /** + * A source for insecure cookie vulnerabilities from model data. + */ + private class ModelsAsDataSource extends Source { + ModelsAsDataSource() { sourceNode(this, "cookie-create") } + } + + /** + * A sink for insecure cookie vulnerabilities from model data. + */ + private class ModelsAsDataSink extends Sink { + ModelsAsDataSink() { sinkNode(this, "cookie-use") } + } +} diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 69d11b85bef3..66ef6db7b0ba 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -16,22 +16,27 @@ import rust import codeql.rust.dataflow.DataFlow import codeql.rust.dataflow.TaintTracking -import codeql.rust.dataflow.FlowSource -import codeql.rust.dataflow.FlowSink +import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' flag set. + * 'secure' attribute set. */ module InsecureCookieConfig implements DataFlow::ConfigSig { + import InsecureCookie + predicate isSource(DataFlow::Node node) { // creation of a cookie or cookie configuration with default, insecure settings - sourceNode(node, "cookie-create") + node instanceof Source } predicate isSink(DataFlow::Node node) { // use of a cookie or cookie configuration - sinkNode(node, "cookie-use") + node instanceof Sink + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Barrier } predicate observeDiffInformedIncrementalMode() { any() } @@ -42,5 +47,6 @@ module InsecureCookieFlow = TaintTracking::Global; import InsecureCookieFlow::PathGraph from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode -where InsecureCookieFlow::flowPath(sourceNode, sinkNode) +where + InsecureCookieFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index 7a1de4f13144..662bcc267743 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -22,13 +22,14 @@ 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.RequestForgeryExtensions +private import codeql.rust.security.HardcodedCryptographicValueExtensions +private import codeql.rust.security.InsecureCookieExtensions private import codeql.rust.security.LogInjectionExtensions +private import codeql.rust.security.RequestForgeryExtensions private import codeql.rust.security.SqlInjectionExtensions private import codeql.rust.security.TaintedPathExtensions private import codeql.rust.security.UncontrolledAllocationSizeExtensions private import codeql.rust.security.WeakSensitiveDataHashingExtensions -private import codeql.rust.security.HardcodedCryptographicValueExtensions /** * Gets a count of the total number of lines of code in the database. From 2654affeee2a5ade67a28eac8efdee108e4328df Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 12:39:50 +0100 Subject: [PATCH 06/22] Rust: Account for the 'secure' and 'partitioned' attributes. --- .../codeql/rust/frameworks/biscotti.model.yml | 4 +- .../codeql/rust/frameworks/cookie.model.yml | 8 +- .../security/InsecureCookieExtensions.qll | 32 +++ .../security/CWE-614/InsecureCookie.ql | 42 +++- .../security/CWE-614/CookieSet.expected | 44 ++++ .../query-tests/security/CWE-614/CookieSet.ql | 7 + .../security/CWE-614/InsecureCookie.expected | 196 +++++++----------- .../test/query-tests/security/CWE-614/main.rs | 14 +- 8 files changed, 213 insertions(+), 134 deletions(-) create mode 100644 rust/ql/test/query-tests/security/CWE-614/CookieSet.expected create mode 100644 rust/ql/test/query-tests/security/CWE-614/CookieSet.ql diff --git a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml index b70a27f74d16..2e9b1213ed76 100644 --- a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml @@ -16,8 +16,8 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: - - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] - ["::set_name", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::set_value", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::set_http_only", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml index f9c8cd647c56..e40fd8ecf71d 100644 --- a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml @@ -26,8 +26,8 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: - - ["::secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] - ["::expires", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::max_age", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::domain", "Argument[self]", "ReturnValue", "taint", "manual"] @@ -36,5 +36,5 @@ extensions: - ["::same_site", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::permanent", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::removal", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 47baa46440c7..aa534a9c1ea6 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -46,4 +46,36 @@ module InsecureCookie { private class ModelsAsDataSink extends Sink { ModelsAsDataSink() { sinkNode(this, "cookie-use") } } + + /** + * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` (`true` or `false`) at `node`. + * A value that cannot be determined is treated as `false`. + * + * This references models-as-data optional barrier nodes, for example `OptionalBarrier[cookie-secure-arg0]`. + */ + predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { + exists( + FlowSummaryNode summaryNode, string barrierName, CallExprBase ce, int arg, + DataFlow::Node argNode + | + // decode a `cookie-`... optional barrier + DataflowImpl::optionalBarrier(summaryNode, barrierName) and + attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and + arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and + // find a call and arg referenced by this optional barrier + ce.getStaticTarget() = summaryNode.getSummarizedCallable() and + ce.getArg(arg) = argNode.asExpr().getExpr() and + // check if the argument is always `true` + ( + if + forex(DataFlow::Node argSourceNode | DataFlow::localFlow(argSourceNode, argNode) | + argSourceNode.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true" + ) + then value = true // `true` flow to here + else value = false // `false` or unknown + ) and + // and the node `node` where this happens + node.asExpr().getExpr() = ce + ) + } } diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 66ef6db7b0ba..987940a2f0ae 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -20,7 +20,8 @@ import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' attribute set. + * 'secure' attribute set. This is the primary data flow configurationn for this + * query. */ module InsecureCookieConfig implements DataFlow::ConfigSig { import InsecureCookie @@ -28,6 +29,9 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { // creation of a cookie or cookie configuration with default, insecure settings node instanceof Source + or + // setting the 'secure' attribute to false (or an unknown value) + cookieSetNode(node, "secure", false) } predicate isSink(DataFlow::Node node) { @@ -36,6 +40,37 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { + // setting the 'secure' attribute to true + cookieSetNode(node, "secure", true) + or + node instanceof Barrier + } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +/** + * A data flow configuration for tracking values representing cookies with the + * 'partitioned' attribute set. This is a secondary data flow configuration used + * to filter out unwanted results. + */ +module PartitionedCookieConfig implements DataFlow::ConfigSig { + import InsecureCookie + + predicate isSource(DataFlow::Node node) { + // setting the 'partitioned' attribute to true + cookieSetNode(node, "partitioned", true) + } + + predicate isSink(DataFlow::Node node) { + // use of a cookie or cookie configuration + node instanceof Sink + } + + predicate isBarrier(DataFlow::Node node) { + // setting the 'partitioned' attribute to false (or an unknown value) + cookieSetNode(node, "partitioned", false) + or node instanceof Barrier } @@ -44,9 +79,12 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { module InsecureCookieFlow = TaintTracking::Global; +module PartitionedCookieFlow = TaintTracking::Global; + import InsecureCookieFlow::PathGraph from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode where - InsecureCookieFlow::flowPath(sourceNode, sinkNode) + InsecureCookieFlow::flowPath(sourceNode, sinkNode) and + not PartitionedCookieFlow::flow(_, sinkNode.getNode()) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected new file mode 100644 index 000000000000..eccdbaec90a0 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -0,0 +1,44 @@ +| main.rs:8:19:8:64 | ... .secure(...) | secure | false | +| main.rs:12:19:12:63 | ... .secure(...) | secure | true | +| main.rs:20:5:20:54 | ... .secure(...) | secure | false | +| main.rs:21:5:21:55 | ... .secure(...) | secure | false | +| main.rs:24:5:24:51 | ... .secure(...) | secure | false | +| main.rs:25:5:25:52 | ... .secure(...) | secure | false | +| main.rs:26:5:26:50 | ... .secure(...) | secure | false | +| main.rs:27:5:27:51 | ... .secure(...) | secure | false | +| main.rs:28:5:28:60 | ... .secure(...) | secure | false | +| main.rs:29:5:29:60 | ... .secure(...) | secure | false | +| main.rs:33:9:33:58 | ... .secure(...) | secure | false | +| main.rs:35:9:35:58 | ... .secure(...) | secure | false | +| main.rs:39:5:39:53 | ... .secure(...) | secure | false | +| main.rs:40:5:40:64 | ... .secure(...) | secure | false | +| main.rs:41:5:41:93 | ... .secure(...) | secure | false | +| main.rs:42:5:42:72 | ... .secure(...) | secure | false | +| main.rs:43:5:43:60 | ... .secure(...) | secure | false | +| main.rs:44:5:44:66 | ... .secure(...) | secure | false | +| main.rs:45:5:45:86 | ... .secure(...) | secure | false | +| main.rs:46:5:46:62 | ... .secure(...) | secure | false | +| main.rs:47:5:47:60 | ... .secure(...) | secure | false | +| main.rs:48:5:48:50 | ... .secure(...) | secure | false | +| main.rs:49:5:49:39 | ... .secure(...) | secure | false | +| main.rs:50:5:50:54 | ... .secure(...) | secure | false | +| main.rs:53:5:53:49 | ... .secure(...) | secure | true | +| main.rs:53:5:53:63 | ... .secure(...) | secure | false | +| main.rs:54:5:54:50 | ... .secure(...) | secure | false | +| main.rs:54:5:54:63 | ... .secure(...) | secure | true | +| main.rs:61:5:61:22 | a.set_secure(...) | secure | true | +| main.rs:63:5:63:23 | a.set_secure(...) | secure | false | +| main.rs:71:5:71:27 | b.set_secure(...) | secure | false | +| main.rs:73:5:73:22 | b.set_secure(...) | secure | true | +| main.rs:81:9:81:26 | c.set_secure(...) | secure | true | +| main.rs:84:5:84:22 | c.set_secure(...) | secure | true | +| main.rs:90:9:90:26 | c.set_secure(...) | secure | true | +| main.rs:92:9:92:31 | c.set_partitioned(...) | partitioned | true | +| main.rs:109:9:109:26 | e.set_secure(...) | secure | true | +| main.rs:114:5:114:54 | ... .partitioned(...) | partitioned | true | +| main.rs:126:13:126:30 | a.set_secure(...) | secure | true | +| main.rs:130:13:130:31 | b.set_secure(...) | secure | false | +| main.rs:134:13:134:35 | c.set_partitioned(...) | partitioned | true | +| main.rs:138:13:138:30 | d.set_secure(...) | secure | true | +| main.rs:142:13:142:36 | e.set_partitioned(...) | partitioned | false | +| main.rs:146:13:146:31 | f.set_secure(...) | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql b/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql new file mode 100644 index 000000000000..c038e6de44b6 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql @@ -0,0 +1,7 @@ +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.security.InsecureCookieExtensions + +from DataFlow::Node node, string state, boolean value +where InsecureCookie::cookieSetNode(node, state, value) +select node, state, value diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index b4bd897ca6ff..9d9975a1a369 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,31 +1,52 @@ #select | main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:12:65:12:69 | build | main.rs:12:19:12:31 | ...::build | main.rs:12:65:12:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | | main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:53:65:53:69 | build | main.rs:53:5:53:17 | ...::build | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:54:65:54:69 | build | main.rs:54:5:54:17 | ...::build | main.rs:54:65:54:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | @@ -40,14 +61,9 @@ | main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:114:56:114:60 | build | main.rs:114:5:114:17 | ...::build | main.rs:114:56:114:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:127:13:127:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:127:13:127:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:131:13:131:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:135:13:135:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:135:13:135:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:139:13:139:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:139:13:139:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:143:13:143:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:143:13:143:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:147:13:147:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | @@ -63,95 +79,85 @@ | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:40 | | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:12:19:12:31 | ...::build | main.rs:12:19:12:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:12:19:12:50 | ...::build(...) | main.rs:12:19:12:63 | ... .secure(...) | provenance | MaD:41 | -| main.rs:12:19:12:63 | ... .secure(...) | main.rs:12:65:12:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:40 | | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:40 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:40 | | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:40 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:40 | | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:40 | | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:40 | | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:40 | | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | -| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:40 | | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | -| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:32 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:40 | | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | -| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:34 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:40 | | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | -| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:31 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:40 | | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | -| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:36 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | -| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:33 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:40 | | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | -| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:39 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:40 | | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | -| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:37 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:40 | | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | -| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:38 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:40 | | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | | main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:40 | | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:40 | | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:53:5:53:17 | ...::build | main.rs:53:5:53:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:53:5:53:36 | ...::build(...) | main.rs:53:5:53:49 | ... .secure(...) | provenance | MaD:41 | -| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:54:5:54:17 | ...::build | main.rs:54:5:54:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:54:5:54:36 | ...::build(...) | main.rs:54:5:54:50 | ... .secure(...) | provenance | MaD:41 | -| main.rs:54:5:54:50 | ... .secure(...) | main.rs:54:5:54:63 | ... .secure(...) | provenance | MaD:41 | -| main.rs:54:5:54:63 | ... .secure(...) | main.rs:54:65:54:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | @@ -217,21 +223,14 @@ edges | main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | | main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:35 | | main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | | main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | -| main.rs:122:9:122:9 | a | main.rs:126:13:126:30 | a.set_secure(...) | provenance | MaD:27 | | main.rs:122:13:122:41 | ...::new | main.rs:122:13:122:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | | main.rs:122:13:122:58 | ...::new(...) | main.rs:122:9:122:9 | a | provenance | | | main.rs:123:20:123:20 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | | main.rs:123:20:123:28 | a.clone() | main.rs:123:13:123:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:126:9:126:9 | b | main.rs:127:20:127:20 | b | provenance | | -| main.rs:126:9:126:9 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | -| main.rs:126:9:126:9 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | -| main.rs:126:13:126:30 | a.set_secure(...) | main.rs:126:9:126:9 | b | provenance | | -| main.rs:127:20:127:20 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | -| main.rs:127:20:127:28 | b.clone() | main.rs:127:13:127:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | | main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | @@ -240,22 +239,9 @@ edges | main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:134:9:134:9 | d | main.rs:135:20:135:20 | d | provenance | | | main.rs:134:9:134:9 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | -| main.rs:134:9:134:9 | d | main.rs:138:13:138:30 | d.set_secure(...) | provenance | MaD:27 | | main.rs:134:13:134:35 | c.set_partitioned(...) | main.rs:134:9:134:9 | d | provenance | | | main.rs:135:20:135:20 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | | main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:138:9:138:9 | e | main.rs:139:20:139:20 | e | provenance | | -| main.rs:138:9:138:9 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | -| main.rs:138:9:138:9 | e | main.rs:142:13:142:36 | e.set_partitioned(...) | provenance | MaD:24 | -| main.rs:138:13:138:30 | d.set_secure(...) | main.rs:138:9:138:9 | e | provenance | | -| main.rs:139:20:139:20 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | -| main.rs:139:20:139:28 | e.clone() | main.rs:139:13:139:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:142:9:142:9 | f | main.rs:143:20:143:20 | f | provenance | | -| main.rs:142:9:142:9 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | -| main.rs:142:9:142:9 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | -| main.rs:142:13:142:36 | e.set_partitioned(...) | main.rs:142:9:142:9 | f | provenance | | -| main.rs:143:20:143:20 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | -| main.rs:143:20:143:28 | f.clone() | main.rs:143:13:143:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | | main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | @@ -295,7 +281,7 @@ edges | main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | | main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | -| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:27 | | main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | | main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | @@ -310,19 +296,19 @@ edges | main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | | main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | -| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:30 | | main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | | main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | | main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | -| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:28 | | main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | | main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | | main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | -| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:29 | | main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | @@ -351,33 +337,28 @@ models | 21 | Summary: ::set_http_only; Argument[self]; ReturnValue; taint | | 22 | Summary: ::set_max_age; Argument[self]; ReturnValue; taint | | 23 | Summary: ::set_name; Argument[self]; ReturnValue; taint | -| 24 | Summary: ::set_partitioned; Argument[self]; ReturnValue; taint | +| 24 | Summary: ::set_partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | | 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | | 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | -| 27 | Summary: ::set_secure; Argument[self]; ReturnValue; taint | -| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | -| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | -| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | -| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | -| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | -| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | -| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | -| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | -| 36 | Summary: ::partitioned; Argument[self]; ReturnValue; taint | -| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | -| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | -| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | -| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | -| 41 | Summary: ::secure; Argument[self]; ReturnValue; taint | +| 27 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 28 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | +| 36 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 37 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | nodes | main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | | main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:8:19:8:64 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:8:66:8:70 | build | semmle.label | build | -| main.rs:12:19:12:31 | ...::build | semmle.label | ...::build | -| main.rs:12:19:12:50 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:12:19:12:63 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:12:65:12:69 | build | semmle.label | build | | main.rs:16:19:16:31 | ...::build | semmle.label | ...::build | | main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:16:52:16:56 | build | semmle.label | build | @@ -477,16 +458,8 @@ nodes | main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:50:56:50:60 | build | semmle.label | build | -| main.rs:53:5:53:17 | ...::build | semmle.label | ...::build | -| main.rs:53:5:53:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:65:53:69 | build | semmle.label | build | -| main.rs:54:5:54:17 | ...::build | semmle.label | ...::build | -| main.rs:54:5:54:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:54:5:54:50 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:54:5:54:63 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:54:65:54:69 | build | semmle.label | build | | main.rs:58:9:58:13 | mut a | semmle.label | mut a | | main.rs:58:17:58:27 | ...::new | semmle.label | ...::new | | main.rs:58:17:58:44 | ...::new(...) | semmle.label | ...::new(...) | @@ -551,11 +524,6 @@ nodes | main.rs:123:13:123:18 | insert | semmle.label | insert | | main.rs:123:20:123:20 | a | semmle.label | a | | main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | -| main.rs:126:9:126:9 | b | semmle.label | b | -| main.rs:126:13:126:30 | a.set_secure(...) | semmle.label | a.set_secure(...) | -| main.rs:127:13:127:18 | insert | semmle.label | insert | -| main.rs:127:20:127:20 | b | semmle.label | b | -| main.rs:127:20:127:28 | b.clone() | semmle.label | b.clone() | | main.rs:130:9:130:9 | c | semmle.label | c | | main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | | main.rs:131:13:131:18 | insert | semmle.label | insert | @@ -566,16 +534,6 @@ nodes | main.rs:135:13:135:18 | insert | semmle.label | insert | | main.rs:135:20:135:20 | d | semmle.label | d | | main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | -| main.rs:138:9:138:9 | e | semmle.label | e | -| main.rs:138:13:138:30 | d.set_secure(...) | semmle.label | d.set_secure(...) | -| main.rs:139:13:139:18 | insert | semmle.label | insert | -| main.rs:139:20:139:20 | e | semmle.label | e | -| main.rs:139:20:139:28 | e.clone() | semmle.label | e.clone() | -| main.rs:142:9:142:9 | f | semmle.label | f | -| main.rs:142:13:142:36 | e.set_partitioned(...) | semmle.label | e.set_partitioned(...) | -| main.rs:143:13:143:18 | insert | semmle.label | insert | -| main.rs:143:20:143:20 | f | semmle.label | f | -| main.rs:143:20:143:28 | f.clone() | semmle.label | f.clone() | | main.rs:146:9:146:9 | g | semmle.label | g | | main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | | main.rs:147:13:147:18 | insert | semmle.label | insert | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 0f0f929fd147..6cbb786cea5a 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -9,7 +9,7 @@ fn test_cookie(sometimes: bool) { println!("cookie1 = '{}'", cookie1.to_string()); // secure set to true - let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) @@ -51,7 +51,7 @@ fn test_cookie(sometimes: bool) { // edge cases Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // good // mutable cookie let mut jar = CookieJar::new(); @@ -111,7 +111,7 @@ fn test_cookie(sometimes: bool) { } // partitioned (implies secure) - Cookie::build(("name", "value")).partitioned(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).partitioned(true).build(); // good } fn test_biscotti() { @@ -124,7 +124,7 @@ fn test_biscotti() { println!("biscotti1 = {}", a.to_string()); let b = a.set_secure(true); - cookies.insert(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(b.clone()); // good println!("biscotti2 = {}", b.to_string()); let c = b.set_secure(false); @@ -132,15 +132,15 @@ fn test_biscotti() { println!("biscotti3 = {}", c.to_string()); let d = c.set_partitioned(true); // (implies secure) - cookies.insert(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(d.clone()); // good println!("biscotti4 = {}", d.to_string()); let e = d.set_secure(true); - cookies.insert(e.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(e.clone()); // good println!("biscotti5 = {}", e.to_string()); let f = e.set_partitioned(false); - cookies.insert(f.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(f.clone()); // good println!("biscotti6 = {}", f.to_string()); let g = f.set_secure(false); From a3ed83bfff14a295405609ba6058f41bf10fd984 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:47:18 +0100 Subject: [PATCH 07/22] Rust: Make state transition / barrier nodes more reliable. --- .../security/InsecureCookieExtensions.qll | 13 +- .../security/CWE-614/CookieSet.expected | 95 ++++---- .../security/CWE-614/InsecureCookie.expected | 220 +++++++++--------- .../test/query-tests/security/CWE-614/main.rs | 6 +- 4 files changed, 176 insertions(+), 158 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index aa534a9c1ea6..93406f914525 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -10,6 +10,7 @@ private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl private import codeql.rust.dataflow.internal.Node +private import codeql.rust.controlflow.BasicBlocks /** * Provides default sources, sinks and barriers for detecting insecure @@ -74,8 +75,16 @@ module InsecureCookie { then value = true // `true` flow to here else value = false // `false` or unknown ) and - // and the node `node` where this happens - node.asExpr().getExpr() = ce + // and find the node where this happens + ( + node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` + or + exists(BasicBlock bb, int i | + // associated SSA node + node.(SsaNode).asDefinition().definesAt(_, bb, i) and + ce.(MethodCallExpr).getReceiver() = bb.getNode(i).getAstNode() + ) + ) ) } } diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index eccdbaec90a0..eacadaa722d9 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -1,44 +1,51 @@ -| main.rs:8:19:8:64 | ... .secure(...) | secure | false | -| main.rs:12:19:12:63 | ... .secure(...) | secure | true | -| main.rs:20:5:20:54 | ... .secure(...) | secure | false | -| main.rs:21:5:21:55 | ... .secure(...) | secure | false | -| main.rs:24:5:24:51 | ... .secure(...) | secure | false | -| main.rs:25:5:25:52 | ... .secure(...) | secure | false | -| main.rs:26:5:26:50 | ... .secure(...) | secure | false | -| main.rs:27:5:27:51 | ... .secure(...) | secure | false | -| main.rs:28:5:28:60 | ... .secure(...) | secure | false | -| main.rs:29:5:29:60 | ... .secure(...) | secure | false | -| main.rs:33:9:33:58 | ... .secure(...) | secure | false | -| main.rs:35:9:35:58 | ... .secure(...) | secure | false | -| main.rs:39:5:39:53 | ... .secure(...) | secure | false | -| main.rs:40:5:40:64 | ... .secure(...) | secure | false | -| main.rs:41:5:41:93 | ... .secure(...) | secure | false | -| main.rs:42:5:42:72 | ... .secure(...) | secure | false | -| main.rs:43:5:43:60 | ... .secure(...) | secure | false | -| main.rs:44:5:44:66 | ... .secure(...) | secure | false | -| main.rs:45:5:45:86 | ... .secure(...) | secure | false | -| main.rs:46:5:46:62 | ... .secure(...) | secure | false | -| main.rs:47:5:47:60 | ... .secure(...) | secure | false | -| main.rs:48:5:48:50 | ... .secure(...) | secure | false | -| main.rs:49:5:49:39 | ... .secure(...) | secure | false | -| main.rs:50:5:50:54 | ... .secure(...) | secure | false | -| main.rs:53:5:53:49 | ... .secure(...) | secure | true | -| main.rs:53:5:53:63 | ... .secure(...) | secure | false | -| main.rs:54:5:54:50 | ... .secure(...) | secure | false | -| main.rs:54:5:54:63 | ... .secure(...) | secure | true | -| main.rs:61:5:61:22 | a.set_secure(...) | secure | true | -| main.rs:63:5:63:23 | a.set_secure(...) | secure | false | -| main.rs:71:5:71:27 | b.set_secure(...) | secure | false | -| main.rs:73:5:73:22 | b.set_secure(...) | secure | true | -| main.rs:81:9:81:26 | c.set_secure(...) | secure | true | -| main.rs:84:5:84:22 | c.set_secure(...) | secure | true | -| main.rs:90:9:90:26 | c.set_secure(...) | secure | true | -| main.rs:92:9:92:31 | c.set_partitioned(...) | partitioned | true | -| main.rs:109:9:109:26 | e.set_secure(...) | secure | true | -| main.rs:114:5:114:54 | ... .partitioned(...) | partitioned | true | -| main.rs:126:13:126:30 | a.set_secure(...) | secure | true | -| main.rs:130:13:130:31 | b.set_secure(...) | secure | false | -| main.rs:134:13:134:35 | c.set_partitioned(...) | partitioned | true | -| main.rs:138:13:138:30 | d.set_secure(...) | secure | true | -| main.rs:142:13:142:36 | e.set_partitioned(...) | partitioned | false | -| main.rs:146:13:146:31 | f.set_secure(...) | secure | false | +| main.rs:8:19:8:50 | ...::build(...) | secure | false | +| main.rs:12:19:12:50 | ...::build(...) | secure | true | +| main.rs:20:5:20:36 | ...::build(...) | secure | false | +| main.rs:21:5:21:36 | ...::build(...) | secure | false | +| main.rs:24:5:24:36 | ...::build(...) | secure | false | +| main.rs:25:5:25:36 | ...::build(...) | secure | false | +| main.rs:26:5:26:36 | ...::build(...) | secure | false | +| main.rs:27:5:27:36 | ...::build(...) | secure | false | +| main.rs:28:5:28:36 | ...::build(...) | secure | false | +| main.rs:29:5:29:36 | ...::build(...) | secure | false | +| main.rs:33:9:33:40 | ...::build(...) | secure | false | +| main.rs:35:9:35:40 | ...::build(...) | secure | false | +| main.rs:39:5:39:39 | ...::new(...) | secure | false | +| main.rs:40:5:40:50 | ... .expires(...) | secure | false | +| main.rs:41:5:41:79 | ... .max_age(...) | secure | false | +| main.rs:42:5:42:58 | ... .domain(...) | secure | false | +| main.rs:43:5:43:46 | ... .path(...) | secure | false | +| main.rs:44:5:44:52 | ... .http_only(...) | secure | false | +| main.rs:45:5:45:72 | ... .same_site(...) | secure | false | +| main.rs:46:5:46:48 | ... .permanent() | secure | false | +| main.rs:47:5:47:46 | ... .removal() | secure | false | +| main.rs:48:5:48:36 | ...::build(...) | secure | false | +| main.rs:49:5:49:25 | ...::build(...) | secure | false | +| main.rs:50:5:50:40 | ...::build(...) | secure | false | +| main.rs:53:5:53:36 | ...::build(...) | secure | true | +| main.rs:53:5:53:49 | ... .secure(...) | secure | false | +| main.rs:54:5:54:36 | ...::build(...) | secure | false | +| main.rs:54:5:54:50 | ... .secure(...) | secure | true | +| main.rs:61:5:61:5 | [SSA] a | secure | true | +| main.rs:61:5:61:5 | a | secure | true | +| main.rs:63:5:63:5 | [SSA] a | secure | false | +| main.rs:63:5:63:5 | a | secure | false | +| main.rs:71:5:71:5 | [SSA] b | secure | false | +| main.rs:71:5:71:5 | b | secure | false | +| main.rs:73:5:73:5 | [SSA] b | secure | true | +| main.rs:73:5:73:5 | b | secure | true | +| main.rs:81:9:81:9 | [SSA] c | secure | true | +| main.rs:81:9:81:9 | c | secure | true | +| main.rs:84:5:84:5 | [SSA] c | secure | true | +| main.rs:84:5:84:5 | c | secure | true | +| main.rs:90:9:90:9 | c | secure | true | +| main.rs:92:9:92:9 | c | partitioned | true | +| main.rs:109:9:109:9 | [SSA] e | secure | true | +| main.rs:109:9:109:9 | e | secure | true | +| main.rs:114:5:114:36 | ...::build(...) | partitioned | true | +| main.rs:126:13:126:13 | a | secure | true | +| main.rs:130:13:130:13 | b | secure | false | +| main.rs:134:13:134:13 | c | partitioned | true | +| main.rs:138:13:138:13 | d | secure | true | +| main.rs:142:13:142:13 | e | partitioned | false | +| main.rs:146:13:146:13 | f | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 9d9975a1a369..880262e9bd4e 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,69 +1,71 @@ #select | main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:8:66:8:70 | build | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:50 | ...::build(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:20:56:20:60 | build | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:36 | ...::build(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:21:57:21:61 | build | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:36 | ...::build(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:25:54:25:58 | build | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:26:52:26:56 | build | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:36 | ...::build(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:27:53:27:57 | build | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:36 | ...::build(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:28:62:28:66 | build | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:36 | ...::build(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:29:62:29:66 | build | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:36 | ...::build(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:33:60:33:64 | build | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:40 | ...::build(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:35:60:35:64 | build | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:40 | ...::build(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:39:55:39:59 | build | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:39 | ...::new(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:40:66:40:70 | build | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:41:95:41:99 | build | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:42:74:42:78 | build | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:43:62:43:66 | build | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:46 | ... .path(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:44:68:44:72 | build | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:45:88:45:92 | build | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:46:64:46:68 | build | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:48 | ... .permanent() | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:47:62:47:66 | build | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:46 | ... .removal() | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | -| main.rs:48:52:48:57 | finish | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:36 | ...::build(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | | main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:49:41:49:45 | build | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:25 | ...::build(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:50:56:50:60 | build | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:53:65:53:69 | build | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:40 | ...::build(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | -| main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:64:9:64:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:63:5:63:5 | [SSA] a | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:63:5:63:5 | a | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:69:16:69:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:69:16:69:18 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:70:16:70:27 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:63:5:63:5 | [SSA] a | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:63:5:63:5 | a | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:72:16:72:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:74:16:74:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:74:16:74:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:71:5:71:5 | [SSA] b | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:71:5:71:5 | b | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:78:17:78:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:78:17:78:19 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:79:17:79:28 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:63:5:63:5 | [SSA] a | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:63:5:63:5 | a | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:83:17:83:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:83:17:83:19 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:131:13:131:18 | insert | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:147:13:147:18 | insert | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:130:13:130:13 | b | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:146:13:146:13 | f | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | @@ -79,129 +81,130 @@ | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:40 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:40 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:40 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:40 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:40 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:40 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:40 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:40 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:40 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | -| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:40 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:32 | -| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:40 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:34 | -| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:40 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:31 | -| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:40 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:36 | -| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:33 | -| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:40 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:39 | -| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:40 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:37 | -| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:40 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:38 | -| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:40 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | | main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:40 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:40 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:13 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:13 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:29 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:30 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | | main.rs:58:17:58:27 | ...::new | main.rs:58:17:58:44 | ...::new(...) | provenance | Src:MaD:15 MaD:15 | | main.rs:58:17:58:44 | ...::new(...) | main.rs:58:9:58:13 | mut a | provenance | | | main.rs:59:13:59:13 | a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:59:13:59:21 | a.clone() | main.rs:59:9:59:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:60:22:60:22 | a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | | main.rs:60:22:60:30 | a.clone() | main.rs:60:9:60:20 | add_original | provenance | MaD:5 Sink:MaD:5 | -| main.rs:62:13:62:13 | a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | -| main.rs:62:13:62:21 | a.clone() | main.rs:62:9:62:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | | main.rs:64:13:64:13 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | | main.rs:64:13:64:21 | a.clone() | main.rs:64:9:64:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:68:9:68:13 | mut b | main.rs:69:20:69:20 | b | provenance | | | main.rs:68:9:68:13 | mut b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | | main.rs:68:9:68:13 | mut b | main.rs:72:20:72:20 | b | provenance | | | main.rs:68:9:68:13 | mut b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | -| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:20 | b | provenance | | -| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | | main.rs:68:17:68:29 | ...::named | main.rs:68:17:68:37 | ...::named(...) | provenance | Src:MaD:14 MaD:14 | | main.rs:68:17:68:37 | ...::named(...) | main.rs:68:9:68:13 | mut b | provenance | | | main.rs:69:20:69:20 | b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | | main.rs:69:20:69:28 | b.clone() | main.rs:69:16:69:18 | add | provenance | MaD:8 Sink:MaD:8 | | main.rs:70:29:70:29 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | | main.rs:70:29:70:37 | a.clone() | main.rs:70:16:70:27 | add_original | provenance | MaD:9 Sink:MaD:9 | +| main.rs:71:5:71:5 | [SSA] b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:71:5:71:5 | [SSA] b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:71:5:71:5 | b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:71:5:71:5 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | | main.rs:72:20:72:20 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | | main.rs:72:20:72:28 | b.clone() | main.rs:72:16:72:18 | add | provenance | MaD:8 Sink:MaD:8 | -| main.rs:74:20:74:20 | b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | -| main.rs:74:20:74:28 | b.clone() | main.rs:74:16:74:18 | add | provenance | MaD:8 Sink:MaD:8 | | main.rs:77:9:77:13 | mut c | main.rs:78:21:78:21 | c | provenance | | | main.rs:77:9:77:13 | mut c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | | main.rs:77:9:77:13 | mut c | main.rs:83:21:83:21 | c | provenance | | | main.rs:77:9:77:13 | mut c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | -| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:21 | c | provenance | | -| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | | main.rs:77:17:77:28 | ...::from | main.rs:77:17:77:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | | main.rs:77:17:77:36 | ...::from(...) | main.rs:77:9:77:13 | mut c | provenance | | | main.rs:78:21:78:21 | c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | @@ -210,8 +213,6 @@ edges | main.rs:79:30:79:38 | a.clone() | main.rs:79:17:79:28 | add_original | provenance | MaD:7 Sink:MaD:7 | | main.rs:83:21:83:21 | c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | | main.rs:83:21:83:29 | c.clone() | main.rs:83:17:83:19 | add | provenance | MaD:6 Sink:MaD:6 | -| main.rs:85:21:85:21 | c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | -| main.rs:85:21:85:29 | c.clone() | main.rs:85:17:85:19 | add | provenance | MaD:6 Sink:MaD:6 | | main.rs:87:9:87:13 | mut d | main.rs:88:13:88:13 | d | provenance | | | main.rs:87:9:87:13 | mut d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | | main.rs:87:9:87:13 | mut d | main.rs:94:13:94:13 | d | provenance | | @@ -223,7 +224,7 @@ edges | main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | | main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:35 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | | main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | | main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | @@ -234,6 +235,7 @@ edges | main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | | main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | +| main.rs:130:13:130:13 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:130:9:130:9 | c | provenance | | | main.rs:131:20:131:20 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | @@ -244,6 +246,7 @@ edges | main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | | main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:146:13:146:13 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | | main.rs:147:20:147:20 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | | main.rs:147:20:147:28 | g.clone() | main.rs:147:13:147:18 | insert | provenance | MaD:1 Sink:MaD:1 | @@ -281,7 +284,7 @@ edges | main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | | main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | -| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:27 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | | main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | | main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | @@ -296,19 +299,19 @@ edges | main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | | main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | -| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:30 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | | main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | | main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | | main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | -| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:28 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | | main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | | main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | | main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | -| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:29 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | | main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | @@ -340,20 +343,21 @@ models | 24 | Summary: ::set_partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | | 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | | 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | -| 27 | Summary: ::set_value; Argument[self]; ReturnValue; taint | -| 28 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | -| 29 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | -| 30 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | -| 31 | Summary: ::domain; Argument[self]; ReturnValue; taint | -| 32 | Summary: ::expires; Argument[self]; ReturnValue; taint | -| 33 | Summary: ::http_only; Argument[self]; ReturnValue; taint | -| 34 | Summary: ::max_age; Argument[self]; ReturnValue; taint | -| 35 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | -| 36 | Summary: ::path; Argument[self]; ReturnValue; taint | -| 37 | Summary: ::permanent; Argument[self]; ReturnValue; taint | -| 38 | Summary: ::removal; Argument[self]; ReturnValue; taint | -| 39 | Summary: ::same_site; Argument[self]; ReturnValue; taint | -| 40 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | +| 27 | Summary: ::set_secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | +| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 36 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | +| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 41 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | nodes | main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | | main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | @@ -458,6 +462,7 @@ nodes | main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:50:56:50:60 | build | semmle.label | build | +| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:65:53:69 | build | semmle.label | build | | main.rs:58:9:58:13 | mut a | semmle.label | mut a | @@ -469,9 +474,8 @@ nodes | main.rs:60:9:60:20 | add_original | semmle.label | add_original | | main.rs:60:22:60:22 | a | semmle.label | a | | main.rs:60:22:60:30 | a.clone() | semmle.label | a.clone() | -| main.rs:62:9:62:11 | add | semmle.label | add | -| main.rs:62:13:62:13 | a | semmle.label | a | -| main.rs:62:13:62:21 | a.clone() | semmle.label | a.clone() | +| main.rs:63:5:63:5 | [SSA] a | semmle.label | [SSA] a | +| main.rs:63:5:63:5 | a | semmle.label | a | | main.rs:64:9:64:11 | add | semmle.label | add | | main.rs:64:13:64:13 | a | semmle.label | a | | main.rs:64:13:64:21 | a.clone() | semmle.label | a.clone() | @@ -484,12 +488,11 @@ nodes | main.rs:70:16:70:27 | add_original | semmle.label | add_original | | main.rs:70:29:70:29 | a | semmle.label | a | | main.rs:70:29:70:37 | a.clone() | semmle.label | a.clone() | +| main.rs:71:5:71:5 | [SSA] b | semmle.label | [SSA] b | +| main.rs:71:5:71:5 | b | semmle.label | b | | main.rs:72:16:72:18 | add | semmle.label | add | | main.rs:72:20:72:20 | b | semmle.label | b | | main.rs:72:20:72:28 | b.clone() | semmle.label | b.clone() | -| main.rs:74:16:74:18 | add | semmle.label | add | -| main.rs:74:20:74:20 | b | semmle.label | b | -| main.rs:74:20:74:28 | b.clone() | semmle.label | b.clone() | | main.rs:77:9:77:13 | mut c | semmle.label | mut c | | main.rs:77:17:77:28 | ...::from | semmle.label | ...::from | | main.rs:77:17:77:36 | ...::from(...) | semmle.label | ...::from(...) | @@ -502,9 +505,6 @@ nodes | main.rs:83:17:83:19 | add | semmle.label | add | | main.rs:83:21:83:21 | c | semmle.label | c | | main.rs:83:21:83:29 | c.clone() | semmle.label | c.clone() | -| main.rs:85:17:85:19 | add | semmle.label | add | -| main.rs:85:21:85:21 | c | semmle.label | c | -| main.rs:85:21:85:29 | c.clone() | semmle.label | c.clone() | | main.rs:87:9:87:13 | mut d | semmle.label | mut d | | main.rs:87:17:87:28 | ...::from | semmle.label | ...::from | | main.rs:87:17:87:36 | ...::from(...) | semmle.label | ...::from(...) | @@ -525,6 +525,7 @@ nodes | main.rs:123:20:123:20 | a | semmle.label | a | | main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | | main.rs:130:9:130:9 | c | semmle.label | c | +| main.rs:130:13:130:13 | b | semmle.label | b | | main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | | main.rs:131:13:131:18 | insert | semmle.label | insert | | main.rs:131:20:131:20 | c | semmle.label | c | @@ -535,6 +536,7 @@ nodes | main.rs:135:20:135:20 | d | semmle.label | d | | main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | | main.rs:146:9:146:9 | g | semmle.label | g | +| main.rs:146:13:146:13 | f | semmle.label | f | | main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | | main.rs:147:13:147:18 | insert | semmle.label | insert | | main.rs:147:20:147:20 | g | semmle.label | g | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 6cbb786cea5a..4cd35ac93142 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -59,7 +59,7 @@ fn test_cookie(sometimes: bool) { jar.add(a.clone()); // $ Alert[rust/insecure-cookie] jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); - jar.add(a.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + jar.add(a.clone()); // good a.set_secure(false); jar.add(a.clone()); // $ Alert[rust/insecure-cookie] @@ -71,7 +71,7 @@ fn test_cookie(sometimes: bool) { b.set_secure(sometimes); signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); - signed_jar.add(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // good let mut private_jar = jar.private_mut(&key); let mut c = Cookie::from("name"); @@ -82,7 +82,7 @@ fn test_cookie(sometimes: bool) { } private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] c.set_secure(true); - private_jar.add(c.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ good let mut d = Cookie::from("name"); jar.add(d.clone()); // $ Alert[rust/insecure-cookie] From 94afc82304b202e74c9114ab56810216a24e545a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:50:46 +0100 Subject: [PATCH 08/22] Rust: Fix an issue with the local flow. --- .../codeql/rust/security/InsecureCookieExtensions.qll | 10 ++++++---- .../query-tests/security/CWE-614/CookieSet.expected | 2 +- .../security/CWE-614/InsecureCookie.expected | 9 --------- rust/ql/test/query-tests/security/CWE-614/main.rs | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 93406f914525..30a033ba155a 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -69,11 +69,13 @@ module InsecureCookie { // check if the argument is always `true` ( if - forex(DataFlow::Node argSourceNode | DataFlow::localFlow(argSourceNode, argNode) | - argSourceNode.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true" + forex(DataFlow::Node argSourceNode, BooleanLiteralExpr argSourceValue | + DataFlow::localFlow(argSourceNode, argNode) and + argSourceValue = argSourceNode.asExpr().getExpr() | + argSourceValue.getTextValue() = "true" ) - then value = true // `true` flow to here - else value = false // `false` or unknown + then value = true // `true` flows to here + else value = false // `false`, unknown, or multiple values ) and // and find the node where this happens ( diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index eacadaa722d9..44f5ff01fbd3 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -2,7 +2,7 @@ | main.rs:12:19:12:50 | ...::build(...) | secure | true | | main.rs:20:5:20:36 | ...::build(...) | secure | false | | main.rs:21:5:21:36 | ...::build(...) | secure | false | -| main.rs:24:5:24:36 | ...::build(...) | secure | false | +| main.rs:24:5:24:36 | ...::build(...) | secure | true | | main.rs:25:5:25:36 | ...::build(...) | secure | false | | main.rs:26:5:26:36 | ...::build(...) | secure | false | | main.rs:27:5:27:36 | ...::build(...) | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 880262e9bd4e..701f90c0f34d 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -6,8 +6,6 @@ | main.rs:20:56:20:60 | build | main.rs:20:5:20:36 | ...::build(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:36 | ...::build(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | @@ -91,9 +89,6 @@ edges | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | -| main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | @@ -374,10 +369,6 @@ nodes | main.rs:21:5:21:36 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:21:5:21:55 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:21:57:21:61 | build | semmle.label | build | -| main.rs:24:5:24:17 | ...::build | semmle.label | ...::build | -| main.rs:24:5:24:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:24:5:24:51 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:24:53:24:57 | build | semmle.label | build | | main.rs:25:5:25:17 | ...::build | semmle.label | ...::build | | main.rs:25:5:25:36 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:25:5:25:52 | ... .secure(...) | semmle.label | ... .secure(...) | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 4cd35ac93142..48671b737a6d 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -21,7 +21,7 @@ fn test_cookie(sometimes: bool) { Cookie::build(("name", "value")).secure(!sometimes).build(); // $ Alert[rust/insecure-cookie] // with data flow on the "secure" value - Cookie::build(("name", "value")).secure(always).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always).build(); // good Cookie::build(("name", "value")).secure(!always).build(); // $ Alert[rust/insecure-cookie] Cookie::build(("name", "value")).secure(never).build(); // $ Alert[rust/insecure-cookie] Cookie::build(("name", "value")).secure(!never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] From bd07350bc3999ca549a31a9e0a3ca01ffa94adb5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:05:11 +0100 Subject: [PATCH 09/22] Rust: Add qhelp and examples. --- .../security/CWE-614/InsecureCookie.qhelp | 33 +++++++++++++++++++ .../security/CWE-614/InsecureCookieBad.rs | 6 ++++ .../security/CWE-614/InsecureCookieGood.rs | 11 +++++++ 3 files changed, 50 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp new file mode 100644 index 000000000000..ef08ff27b9c3 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -0,0 +1,33 @@ + + + + +

Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic (for example over an insecure Wi‑Fi network), they can access sensitive information in the cookie and potentially use it to impersonate the user.

+ +
+ + +

Always set the cookie 'Secure' attribute so that the browser only sends the cookie over HTTPS.

+ +
+ + +

The following example creates a cookie using the cookie crate without the 'Secure' attribute:

+ + + +

In the fixed example, we either call secure(true) on the CookieBuilder or set_secure(true) on the Cookie itself:

+ + + +
+ + +
  • MDN Web Docs: Using HTTP cookies.
  • +
  • OWASP Cheat Sheet Series: Session Management Cheat Sheet - Transport Layer Security.
  • +
  • MDN Web Docs: Set-Cookie header - Secure.
  • + +
    +
    diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs new file mode 100644 index 000000000000..239776e99de4 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs @@ -0,0 +1,6 @@ +use cookie::Cookie; + +// BAD: creating a cookie without specifying the `secure` attribute +let cookie = Cookie::build("session", "abcd1234").build(); +let mut jar = cookie::CookieJar::new(); +jar.add(cookie.clone()); diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs new file mode 100644 index 000000000000..81971552d0f8 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs @@ -0,0 +1,11 @@ +use cookie::Cookie; + +// GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS +let secure_cookie = Cookie::build("session", "abcd1234").secure(true).build(); +let mut jar = cookie::CookieJar::new(); +jar.add(secure_cookie.clone()); + +// GOOD: alternatively, set the 'Secure' attribute on an existing `Cookie` +let mut secure_cookie2 = Cookie::new("session", "abcd1234"); +secure_cookie2.set_secure(true); +jar.add(secure_cookie2); From 4662e42584d13987d8d5a09c7edaef137db8c325 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 15:00:14 +0100 Subject: [PATCH 10/22] Rust: Add examples as tests (and fix them). --- .../security/CWE-614/InsecureCookieBad.rs | 2 +- .../security/CWE-614/InsecureCookieGood.rs | 2 +- .../security/CWE-614/CookieSet.expected | 3 +++ .../security/CWE-614/InsecureCookie.expected | 6 +++++ .../test/query-tests/security/CWE-614/main.rs | 22 +++++++++++++++++++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs index 239776e99de4..e4939f6d5c85 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs @@ -1,6 +1,6 @@ use cookie::Cookie; // BAD: creating a cookie without specifying the `secure` attribute -let cookie = Cookie::build("session", "abcd1234").build(); +let cookie = Cookie::build(("session", "abcd1234")).build(); let mut jar = cookie::CookieJar::new(); jar.add(cookie.clone()); diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs index 81971552d0f8..886d969604cd 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs @@ -1,7 +1,7 @@ use cookie::Cookie; // GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS -let secure_cookie = Cookie::build("session", "abcd1234").secure(true).build(); +let secure_cookie = Cookie::build(("session", "abcd1234")).secure(true).build(); let mut jar = cookie::CookieJar::new(); jar.add(secure_cookie.clone()); diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index 44f5ff01fbd3..959648d37ed1 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -49,3 +49,6 @@ | main.rs:138:13:138:13 | d | secure | true | | main.rs:142:13:142:13 | e | partitioned | false | | main.rs:146:13:146:13 | f | secure | false | +| main.rs:180:29:180:66 | ...::build(...) | secure | true | +| main.rs:186:9:186:22 | [SSA] secure_cookie2 | secure | true | +| main.rs:186:9:186:22 | secure_cookie2 | secure | true | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 701f90c0f34d..e514828c3a0c 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -77,6 +77,7 @@ | main.rs:165:13:165:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:165:13:165:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:166:13:166:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:166:13:166:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:173:61:173:65 | build | main.rs:173:22:173:34 | ...::build | main.rs:173:61:173:65 | build | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | @@ -311,6 +312,8 @@ edges | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | | main.rs:167:20:167:45 | ... .make_permanent() | main.rs:167:13:167:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:173:22:173:34 | ...::build | main.rs:173:22:173:59 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:173:22:173:59 | ...::build(...) | main.rs:173:61:173:65 | build | provenance | MaD:2 Sink:MaD:2 | models | 1 | Sink: ::insert; Argument[0]; cookie-use | | 2 | Sink: ::build; Argument[self]; cookie-use | @@ -588,4 +591,7 @@ nodes | main.rs:167:20:167:20 | i | semmle.label | i | | main.rs:167:20:167:28 | i.clone() | semmle.label | i.clone() | | main.rs:167:20:167:45 | ... .make_permanent() | semmle.label | ... .make_permanent() | +| main.rs:173:22:173:34 | ...::build | semmle.label | ...::build | +| main.rs:173:22:173:59 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:173:61:173:65 | build | semmle.label | build | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 48671b737a6d..e14ac6719d69 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -167,8 +167,30 @@ fn test_biscotti() { cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } +fn test_qhelp_examples() {use cookie::Cookie; + { + // BAD: creating a cookie without specifying the `secure` attribute + let cookie = Cookie::build(("session", "abcd1234")).build(); // $ Alert[rust/insecure-cookie] + let mut jar = cookie::CookieJar::new(); + jar.add(cookie.clone()); + } + + { + // GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS + let secure_cookie = Cookie::build(("session", "abcd1234")).secure(true).build(); + let mut jar = cookie::CookieJar::new(); + jar.add(secure_cookie.clone()); + + // GOOD: alternatively, set the 'Secure' attribute on an existing `Cookie` + let mut secure_cookie2 = Cookie::new("session", "abcd1234"); + secure_cookie2.set_secure(true); + jar.add(secure_cookie2); + } +} + fn main() { test_cookie(true); test_cookie(false); test_biscotti(); + test_qhelp_examples(); } From ae9025334e747e6170d89b3be583bed11627afce Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:31:34 +0100 Subject: [PATCH 11/22] Rust: Add the new query to suite 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 b601905e6a30..2035af152182 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 @@ -16,6 +16,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/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-798/HardcodedCryptographicValue.ql ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.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 074cb2ec8888..960ba9079cc0 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 @@ -17,6 +17,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/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-798/HardcodedCryptographicValue.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 38846e281eb8..d758b7ac8d52 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 @@ -17,6 +17,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/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-798/HardcodedCryptographicValue.ql ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql From 3de191177cdb21b20495f11e54503d4a83d173d8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:35:54 +0100 Subject: [PATCH 12/22] Rust: Change note. --- rust/ql/src/change-notes/2025-09-19-insecure-cookie.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 rust/ql/src/change-notes/2025-09-19-insecure-cookie.md diff --git a/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md b/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md new file mode 100644 index 000000000000..d84da707c43c --- /dev/null +++ b/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `rust/insecure-cookie`, to detect cookies created without the 'Secure' attribute. From cc9c4149d7ae4ce30fc6fe0d3717076ab70ad801 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:54:08 +0100 Subject: [PATCH 13/22] Apply suggestions from code review --- rust/ql/test/query-tests/security/CWE-614/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index e14ac6719d69..674ad95a7ba4 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -167,7 +167,7 @@ fn test_biscotti() { cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } -fn test_qhelp_examples() {use cookie::Cookie; +fn test_qhelp_examples() { { // BAD: creating a cookie without specifying the `secure` attribute let cookie = Cookie::build(("session", "abcd1234")).build(); // $ Alert[rust/insecure-cookie] From 5b4632b4326765014dfb8d4532ce1807c206ee37 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:55:43 +0100 Subject: [PATCH 14/22] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 987940a2f0ae..e215bd65f034 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -20,7 +20,7 @@ import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' attribute set. This is the primary data flow configurationn for this + * 'secure' attribute set. This is the primary data flow configuration for this * query. */ module InsecureCookieConfig implements DataFlow::ConfigSig { From 43ac75ed625e3e5d0fe6d2a06b6e4d1566b53fbb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:58:07 +0100 Subject: [PATCH 15/22] Rust: Address another tiny suggestion from review. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 30a033ba155a..0dea9844d0b9 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -8,7 +8,7 @@ private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.FlowSource private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts -private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl +private import codeql.rust.dataflow.internal.DataFlowImpl as DataFlowImpl private import codeql.rust.dataflow.internal.Node private import codeql.rust.controlflow.BasicBlocks @@ -60,7 +60,7 @@ module InsecureCookie { DataFlow::Node argNode | // decode a `cookie-`... optional barrier - DataflowImpl::optionalBarrier(summaryNode, barrierName) and + DataFlowImpl::optionalBarrier(summaryNode, barrierName) and attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and // find a call and arg referenced by this optional barrier From 6362884d1683e8674775bc514537f90768ebbbba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:59:11 +0100 Subject: [PATCH 16/22] Rust: Autoformat. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 0dea9844d0b9..3525614c0dc6 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -71,7 +71,8 @@ module InsecureCookie { if forex(DataFlow::Node argSourceNode, BooleanLiteralExpr argSourceValue | DataFlow::localFlow(argSourceNode, argNode) and - argSourceValue = argSourceNode.asExpr().getExpr() | + argSourceValue = argSourceNode.asExpr().getExpr() + | argSourceValue.getTextValue() = "true" ) then value = true // `true` flows to here From 86c8c3c8c09e98ca7a8f04ae692d431b90699bb0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:01:12 +0100 Subject: [PATCH 17/22] Rust: Fix warning by making the query a path-problem. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index e215bd65f034..e2d7288db45b 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -3,7 +3,7 @@ * @description Omitting the 'Secure' attribute allows data to be transmitted insecurely * using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS * is used at all times. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 7.5 * @precision high From 266624dd0f653a237c6a863d2e49370f68388669 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:12:52 +0100 Subject: [PATCH 18/22] Rust: The test needs to have Source tags now. --- .../test/query-tests/security/CWE-614/main.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 674ad95a7ba4..afcbb28931f1 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -55,26 +55,26 @@ fn test_cookie(sometimes: bool) { // mutable cookie let mut jar = CookieJar::new(); - let mut a = Cookie::new("name", "value"); + let mut a = Cookie::new("name", "value"); // $ Source jar.add(a.clone()); // $ Alert[rust/insecure-cookie] jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); jar.add(a.clone()); // good - a.set_secure(false); + a.set_secure(false); // $ Source jar.add(a.clone()); // $ Alert[rust/insecure-cookie] let key = Key::generate(); let mut signed_jar = jar.signed_mut(&key); - let mut b = Cookie::named("name"); + let mut b = Cookie::named("name"); // $ Source signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] signed_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] - b.set_secure(sometimes); + b.set_secure(sometimes); // $ Source signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); signed_jar.add(b.clone()); // good let mut private_jar = jar.private_mut(&key); - let mut c = Cookie::from("name"); + let mut c = Cookie::from("name"); // $ Source private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] private_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] if sometimes { @@ -84,7 +84,7 @@ fn test_cookie(sometimes: bool) { c.set_secure(true); private_jar.add(c.clone()); // $ good - let mut d = Cookie::from("name"); + let mut d = Cookie::from("name"); // $ Source jar.add(d.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); @@ -119,7 +119,7 @@ fn test_biscotti() { // test set_secure, set_partitioned - let a = biscotti::ResponseCookie::new("name", "value"); + let a = biscotti::ResponseCookie::new("name", "value"); // $ Source cookies.insert(a.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti1 = {}", a.to_string()); @@ -127,7 +127,7 @@ fn test_biscotti() { cookies.insert(b.clone()); // good println!("biscotti2 = {}", b.to_string()); - let c = b.set_secure(false); + let c = b.set_secure(false); // $ Source cookies.insert(c.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti3 = {}", c.to_string()); @@ -143,16 +143,16 @@ fn test_biscotti() { cookies.insert(f.clone()); // good println!("biscotti6 = {}", f.to_string()); - let g = f.set_secure(false); + let g = f.set_secure(false); // $ Source cookies.insert(g.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti7 = {}", g.to_string()); // variant creation (insecure) - let h = biscotti::ResponseCookie::from(("name", "value")); + let h = biscotti::ResponseCookie::from(("name", "value")); // $ Source cookies.insert(h); // $ Alert[rust/insecure-cookie] // variant uses (all insecure) - let i = biscotti::ResponseCookie::new("name", "value"); + let i = biscotti::ResponseCookie::new("name", "value"); // $ Source cookies.insert(i.clone().set_name("name2")); // $ Alert[rust/insecure-cookie] cookies.insert(i.clone().set_value("value2")); // $ Alert[rust/insecure-cookie] cookies.insert(i.clone().set_http_only(true)); // $ Alert[rust/insecure-cookie] From 21fe142955f3c1285ae832f51765756181bc25aa Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:39:49 +0100 Subject: [PATCH 19/22] Update rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp Co-authored-by: Simon Friis Vindum --- rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp index ef08ff27b9c3..f3d1735251e6 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -14,7 +14,7 @@ -

    The following example creates a cookie using the cookie crate without the 'Secure' attribute:

    +

    The following example creates a cookie using the cookie crate without the 'Secure' attribute:

    From 57f84873b441399cdea83ea429301a2119cb1cda Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:29:11 +0100 Subject: [PATCH 20/22] Rust: Split off cookieOptionalBarrier predicate (as suggested) and expand / clarify the QLDoc. --- .../security/InsecureCookieExtensions.qll | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 3525614c0dc6..721f30c1a376 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -49,20 +49,40 @@ module InsecureCookie { } /** - * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` (`true` or `false`) at `node`. - * A value that cannot be determined is treated as `false`. + * Holds if a models-as-data optional barrier for cookies is specified for `summaryNode`, + * with arguments `attrib` (`secure` or `partitioned`) and `arg` (argument index). For example, + * if a summary has input: + * ``` + * [..., Argument[self].OptionalBarrier[cookie-secure-arg0], ...] + * ``` + * then `attrib` is `secure` and `arg` is `0`. * - * This references models-as-data optional barrier nodes, for example `OptionalBarrier[cookie-secure-arg0]`. + * The meaning here is that a call to the function summarized by `summaryNode` would set + * the cookie attribute `attrib` to the value of argument `arg`. This may in practice be + * interpretted as a barrier to flow (when the cookie is made secure) or as a source (when + * the cookie is made insecure). */ - predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { - exists( - FlowSummaryNode summaryNode, string barrierName, CallExprBase ce, int arg, - DataFlow::Node argNode - | - // decode a `cookie-`... optional barrier + private predicate cookieOptionalBarrier(FlowSummaryNode summaryNode, string attrib, int arg) { + exists(string barrierName | DataFlowImpl::optionalBarrier(summaryNode, barrierName) and attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and - arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and + arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() + ) + } + + /** + * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` + * (`true` or `false`) at `node`. For example, the call: + * ``` + * cookie.secure(true) + * ``` + * sets the `"secure"` attribute to `true`. A value that cannot be determined is treated + * as `false`. + */ + predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { + exists(FlowSummaryNode summaryNode, CallExprBase ce, int arg, DataFlow::Node argNode | + // decode the models-as-data `OptionalBarrier` + cookieOptionalBarrier(summaryNode, attrib, arg) and // find a call and arg referenced by this optional barrier ce.getStaticTarget() = summaryNode.getSummarizedCallable() and ce.getArg(arg) = argNode.asExpr().getExpr() and @@ -78,7 +98,8 @@ module InsecureCookie { then value = true // `true` flows to here else value = false // `false`, unknown, or multiple values ) and - // and find the node where this happens + // and find the node where this happens (we can't just use the flow summary node, since its + // shared across all calls to the modelled function, we need a node specific to this call) ( node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` or From f458149655c1bf7ab9b8673fb480926e65d0d86a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:32:45 +0100 Subject: [PATCH 21/22] Rust: Remove a sentance from the qhelp. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp index f3d1735251e6..561b334c5101 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -4,7 +4,7 @@ -

    Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic (for example over an insecure Wi‑Fi network), they can access sensitive information in the cookie and potentially use it to impersonate the user.

    +

    Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic, they can access sensitive information in the cookie and potentially use it to impersonate the user.

    From 77e7898f718087df6debe850bbc74e9946957289 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:49:23 +0100 Subject: [PATCH 22/22] Rust: Use US spelling in comment. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 721f30c1a376..d5d15c821d87 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -99,7 +99,7 @@ module InsecureCookie { else value = false // `false`, unknown, or multiple values ) and // and find the node where this happens (we can't just use the flow summary node, since its - // shared across all calls to the modelled function, we need a node specific to this call) + // shared across all calls to the modeled function, we need a node specific to this call) ( node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` or