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 diff --git a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml index c99a2433348a..2e9b1213ed76 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].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"] + - ["::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..e40fd8ecf71d 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].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"] + - ["::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].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 new file mode 100644 index 000000000000..d5d15c821d87 --- /dev/null +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -0,0 +1,114 @@ +/** + * 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 +private import codeql.rust.controlflow.BasicBlocks + +/** + * 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") } + } + + /** + * 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`. + * + * 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). + */ + 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() + ) + } + + /** + * 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 + // check if the argument is always `true` + ( + if + forex(DataFlow::Node argSourceNode, BooleanLiteralExpr argSourceValue | + DataFlow::localFlow(argSourceNode, argNode) and + argSourceValue = argSourceNode.asExpr().getExpr() + | + argSourceValue.getTextValue() = "true" + ) + then value = true // `true` flows to here + 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 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 + 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/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. 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..561b334c5101 --- /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, 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/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql new file mode 100644 index 000000000000..e2d7288db45b --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -0,0 +1,90 @@ +/** + * @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 path-problem + * @problem.severity error + * @security-severity 7.5 + * @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 codeql.rust.security.InsecureCookieExtensions + +/** + * A data flow configuration for tracking values representing cookies without the + * 'secure' attribute set. This is the primary data flow configuration for this + * query. + */ +module InsecureCookieConfig implements DataFlow::ConfigSig { + import InsecureCookie + + 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) { + // use of a cookie or cookie configuration + node instanceof Sink + } + + 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 + } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +module InsecureCookieFlow = TaintTracking::Global; + +module PartitionedCookieFlow = TaintTracking::Global; + +import InsecureCookieFlow::PathGraph + +from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode +where + 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/src/queries/security/CWE-614/InsecureCookieBad.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs new file mode 100644 index 000000000000..e4939f6d5c85 --- /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..886d969604cd --- /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); 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. 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/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected new file mode 100644 index 000000000000..959648d37ed1 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -0,0 +1,54 @@ +| 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 | 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 | +| 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 | +| 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/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 new file mode 100644 index 000000000000..e514828c3a0c --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -0,0 +1,597 @@ +#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: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: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: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. | +| 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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. | +| 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. | +| 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 | +| 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: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: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: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: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: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: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: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: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: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: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: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 | +| 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: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: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 | +| 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 | +| 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 | +| 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].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].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(...) | +| main.rs:8:19:8:64 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:8:66:8:70 | 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: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: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 | +| 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: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() | +| 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: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: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: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: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 | +| 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: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 | +| 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() | +| 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/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 new file mode 100644 index 000000000000..afcbb28931f1 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -0,0 +1,196 @@ +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(); // $ 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(); // $ Alert[rust/insecure-cookie] + println!("cookie3 = '{}'", cookie3.to_string()); + + // secure setting varies (may be false) + 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(); // $ 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(); // $ SPURIOUS: Alert[rust/insecure-cookie] + } else { + Cookie::build(("name", "value")).secure(sometimes).build(); // $ Alert[rust/insecure-cookie] + } + + // variant uses (all insecure) + 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(); // $ 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"); // $ 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); // $ 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"); // $ Source + signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] + signed_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] + 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"); // $ Source + 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()); // $ Alert[rust/insecure-cookie] + c.set_secure(true); + private_jar.add(c.clone()); // $ good + + let mut d = Cookie::from("name"); // $ Source + jar.add(d.clone()); // $ Alert[rust/insecure-cookie] + if sometimes { + c.set_secure(true); + } else { + c.set_partitioned(true); + } + jar.add(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + + // 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"); // $ Source + cookies.insert(a.clone()); // $ Alert[rust/insecure-cookie] + println!("biscotti1 = {}", a.to_string()); + + let b = a.set_secure(true); + cookies.insert(b.clone()); // good + println!("biscotti2 = {}", b.to_string()); + + let c = b.set_secure(false); // $ Source + 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 + println!("biscotti4 = {}", d.to_string()); + + let e = d.set_secure(true); + cookies.insert(e.clone()); // good + println!("biscotti5 = {}", e.to_string()); + + let f = e.set_partitioned(false); + cookies.insert(f.clone()); // good + println!("biscotti6 = {}", f.to_string()); + + 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")); // $ Source + cookies.insert(h); // $ Alert[rust/insecure-cookie] + + // variant uses (all insecure) + 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] + 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 test_qhelp_examples() { + { + // 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(); +} 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" }