mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Merge pull request #19000 from paldepind/rust-cleartext-transmission
Rust: Add cleartext transmission query
This commit is contained in:
@@ -5,6 +5,12 @@ extensions:
|
||||
data:
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::get", "ReturnValue.Field[crate::result::Result::Ok(0)]", "remote", "manual"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::blocking::get", "ReturnValue.Field[crate::result::Result::Ok(0)]", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::request", "Argument[1]", "transmission", "manual"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::request", "Argument[1]", "transmission", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: summaryModel
|
||||
|
||||
7
rust/ql/lib/codeql/rust/frameworks/url.model.yml
Normal file
7
rust/ql/lib/codeql/rust/frameworks/url.model.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
# Models for the `url` crate
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["repo:https://github.com/servo/rust-url:url", "<crate::Url>::parse", "Argument[0].Reference", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Provides classes and predicates for reasoning about cleartext transmission
|
||||
* vulnerabilities.
|
||||
*/
|
||||
|
||||
private import codeql.util.Unit
|
||||
private import rust
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.dataflow.FlowSink
|
||||
|
||||
/**
|
||||
* A data flow sink for cleartext transmission vulnerabilities. That is,
|
||||
* a `DataFlow::Node` of something that is transmitted over a network.
|
||||
*/
|
||||
abstract class CleartextTransmissionSink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A barrier for cleartext transmission vulnerabilities.
|
||||
*/
|
||||
abstract class CleartextTransmissionBarrier extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A unit class for adding additional flow steps.
|
||||
*/
|
||||
class CleartextTransmissionAdditionalFlowStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `node1` to `node2` should be considered a flow
|
||||
* step for paths related to cleartext transmission vulnerabilities.
|
||||
*/
|
||||
abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink defined through MaD.
|
||||
*/
|
||||
private class MadCleartextTransmissionSink extends CleartextTransmissionSink {
|
||||
MadCleartextTransmissionSink() { sinkNode(this, "transmission") }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT.
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::delete", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::get", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::head", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::patch", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::post", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::async_impl::client::Client>::put", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::delete", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::get", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::head", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::patch", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::post", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::blocking::client::Client>::put", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::connect::Connector as crate::Service>::call", "Argument[0]", "log-injection", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "<crate::connect::ConnectorService as crate::Service>::call", "Argument[0]", "log-injection", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::blocking::get", "Argument[0]", "transmission", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::blocking::wait::timeout", "Argument[1]", "log-injection", "df-generated"]
|
||||
- ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::get", "Argument[0]", "transmission", "df-generated"]
|
||||
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
|
||||
<p>
|
||||
Sensitive information that is transmitted without encryption may be accessible
|
||||
to an attacker.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Ensure that sensitive information is always encrypted before being transmitted
|
||||
over the network. In general, decrypt sensitive information only at the point
|
||||
where it is necessary for it to be used in cleartext. Avoid transmitting
|
||||
sensitive information when it is not necessary to.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following example shows three cases of transmitting information. In the
|
||||
'BAD' case, the transmitted data is sensitive (a credit card number) and is
|
||||
included as cleartext in the URL. URLs are often logged or otherwise visible in
|
||||
cleartext, and should not contain sensitive information.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the 'GOOD' cases, the data is either not sensitive, or is protected with
|
||||
encryption. When encryption is used, ensure that you select a secure modern
|
||||
encryption algorithm, and put suitable key management practices into place.
|
||||
</p>
|
||||
|
||||
<sample src="CleartextTransmission.rs" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
OWASP Top 10:2021:
|
||||
<a href="https://owasp.org/Top10/A02_2021-Cryptographic_Failures/">A02:2021 - Cryptographic Failures</a>.
|
||||
</li>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html">Key Management Cheat Sheet</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @name Cleartext transmission of sensitive information
|
||||
* @description Transmitting sensitive information across a network in
|
||||
* cleartext can expose it to an attacker.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @id rust/cleartext-transmission
|
||||
* @tags security
|
||||
* external/cwe/cwe-319
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.security.SensitiveData
|
||||
import codeql.rust.dataflow.TaintTracking
|
||||
import codeql.rust.security.CleartextTransmissionExtensions
|
||||
|
||||
/**
|
||||
* A taint configuration from sensitive information to expressions that are
|
||||
* transmitted over a network.
|
||||
*/
|
||||
module CleartextTransmissionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof SensitiveData }
|
||||
|
||||
predicate isSink(DataFlow::Node node) { node instanceof CleartextTransmissionSink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof CleartextTransmissionBarrier }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
any(CleartextTransmissionAdditionalFlowStep s).step(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
// make sources barriers so that we only report the closest instance
|
||||
isSource(node)
|
||||
}
|
||||
}
|
||||
|
||||
module CleartextTransmissionFlow = TaintTracking::Global<CleartextTransmissionConfig>;
|
||||
|
||||
import CleartextTransmissionFlow::PathGraph
|
||||
|
||||
from CleartextTransmissionFlow::PathNode sourceNode, CleartextTransmissionFlow::PathNode sinkNode
|
||||
where CleartextTransmissionFlow::flowPath(sourceNode, sinkNode)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode,
|
||||
"The operation '" + sinkNode.getNode().toString() +
|
||||
"', transmits data which may contain unencrypted sensitive data from $@.", sourceNode,
|
||||
sourceNode.getNode().toString()
|
||||
@@ -0,0 +1,15 @@
|
||||
func getData() {
|
||||
// ...
|
||||
|
||||
// GOOD: not sensitive information
|
||||
let body = reqwest::get("https://example.com/song/{faveSong}").await?.text().await?;
|
||||
|
||||
// BAD: sensitive information sent in cleartext in the URL
|
||||
let body = reqwest::get(format!("https://example.com/card/{creditCardNo}")).await?.text().await?;
|
||||
|
||||
// GOOD: encrypted sensitive information sent in the URL
|
||||
let encryptedPassword = encrypt(password, encryptionKey);
|
||||
let body = reqwest::get(format!("https://example.com/card/{creditCardNo}")).await?.text().await?;
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -2216,6 +2216,7 @@ storeStep
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::chunk | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::chunk |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text_with_charset |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout |
|
||||
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_ms | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_ms |
|
||||
@@ -2495,6 +2496,7 @@ readStep
|
||||
| file://:0:0:0:0 | [summary param] 0 in lang:std::_::crate::thread::current::try_with_current | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:std::_::crate::thread::current::try_with_current |
|
||||
| file://:0:0:0:0 | [summary param] 0 in lang:std::_::crate::thread::with_current_name | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:std::_::crate::thread::with_current_name |
|
||||
| file://:0:0:0:0 | [summary param] 0 in repo:https://github.com/rust-lang/regex:regex::_::crate::escape | &ref | file://:0:0:0:0 | [summary] read: Argument[0].Reference in repo:https://github.com/rust-lang/regex:regex::_::crate::escape |
|
||||
| file://:0:0:0:0 | [summary param] 0 in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse | &ref | file://:0:0:0:0 | [summary] read: Argument[0].Reference in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse |
|
||||
| file://:0:0:0:0 | [summary param] 1 in lang:alloc::_::<crate::vec::into_iter::IntoIter as crate::iter::traits::iterator::Iterator>::fold | function return | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:alloc::_::<crate::vec::into_iter::IntoIter as crate::iter::traits::iterator::Iterator>::fold |
|
||||
| file://:0:0:0:0 | [summary param] 1 in lang:alloc::_::crate::collections::btree::mem::replace | function return | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:alloc::_::crate::collections::btree::mem::replace |
|
||||
| file://:0:0:0:0 | [summary param] 1 in lang:alloc::_::crate::collections::btree::mem::take_mut | function return | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:alloc::_::crate::collections::btree::mem::take_mut |
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
| main.rs:6:25:6:30 | ®ex | main.rs:4:20:4:32 | ...::var | main.rs:6:25:6:30 | ®ex | This regular expression is constructed from a $@. | main.rs:4:20:4:32 | ...::var | user-provided value |
|
||||
edges
|
||||
| main.rs:4:9:4:16 | username | main.rs:5:25:5:44 | MacroExpr | provenance | |
|
||||
| main.rs:4:20:4:32 | ...::var | main.rs:4:20:4:40 | ...::var(...) [Ok] | provenance | Src:MaD:60 |
|
||||
| main.rs:4:20:4:40 | ...::var(...) [Ok] | main.rs:4:20:4:66 | ... .unwrap_or(...) | provenance | MaD:1573 |
|
||||
| main.rs:4:20:4:32 | ...::var | main.rs:4:20:4:40 | ...::var(...) [Ok] | provenance | Src:MaD:62 |
|
||||
| main.rs:4:20:4:40 | ...::var(...) [Ok] | main.rs:4:20:4:66 | ... .unwrap_or(...) | provenance | MaD:1593 |
|
||||
| main.rs:4:20:4:66 | ... .unwrap_or(...) | main.rs:4:9:4:16 | username | provenance | |
|
||||
| main.rs:5:9:5:13 | regex | main.rs:6:26:6:30 | regex | provenance | |
|
||||
| main.rs:5:17:5:45 | res | main.rs:5:25:5:44 | { ... } | provenance | |
|
||||
| main.rs:5:25:5:44 | ...::format(...) | main.rs:5:17:5:45 | res | provenance | |
|
||||
| main.rs:5:25:5:44 | ...::must_use(...) | main.rs:5:9:5:13 | regex | provenance | |
|
||||
| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:64 |
|
||||
| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:2996 |
|
||||
| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:66 |
|
||||
| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:3016 |
|
||||
| main.rs:6:26:6:30 | regex | main.rs:6:25:6:30 | ®ex | provenance | |
|
||||
nodes
|
||||
| main.rs:4:9:4:16 | username | semmle.label | username |
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#select
|
||||
| main.rs:7:5:7:26 | ...::get | main.rs:6:50:6:57 | password | main.rs:7:5:7:26 | ...::get | The operation '...::get', transmits data which may contain unencrypted sensitive data from $@. | main.rs:6:50:6:57 | password | password |
|
||||
| main.rs:14:5:14:26 | ...::get | main.rs:12:50:12:57 | password | main.rs:14:5:14:26 | ...::get | The operation '...::get', transmits data which may contain unencrypted sensitive data from $@. | main.rs:12:50:12:57 | password | password |
|
||||
| main.rs:21:12:21:15 | post | main.rs:19:50:19:57 | password | main.rs:21:12:21:15 | post | The operation 'post', transmits data which may contain unencrypted sensitive data from $@. | main.rs:19:50:19:57 | password | password |
|
||||
| main.rs:28:12:28:18 | request | main.rs:26:50:26:57 | password | main.rs:28:12:28:18 | request | The operation 'request', transmits data which may contain unencrypted sensitive data from $@. | main.rs:26:50:26:57 | password | password |
|
||||
| main.rs:35:12:35:18 | request | main.rs:33:50:33:57 | password | main.rs:35:12:35:18 | request | The operation 'request', transmits data which may contain unencrypted sensitive data from $@. | main.rs:33:50:33:57 | password | password |
|
||||
edges
|
||||
| main.rs:6:9:6:11 | url | main.rs:7:28:7:30 | url | provenance | |
|
||||
| main.rs:6:15:6:58 | res | main.rs:6:23:6:57 | { ... } | provenance | |
|
||||
| main.rs:6:23:6:57 | ...::format(...) | main.rs:6:15:6:58 | res | provenance | |
|
||||
| main.rs:6:23:6:57 | ...::must_use(...) | main.rs:6:9:6:11 | url | provenance | |
|
||||
| main.rs:6:23:6:57 | MacroExpr | main.rs:6:23:6:57 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:6:23:6:57 | { ... } | main.rs:6:23:6:57 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:6:50:6:57 | password | main.rs:6:23:6:57 | MacroExpr | provenance | |
|
||||
| main.rs:7:28:7:30 | url | main.rs:7:5:7:26 | ...::get | provenance | MaD:4 Sink:MaD:4 |
|
||||
| main.rs:12:9:12:15 | address | main.rs:13:27:13:33 | address | provenance | |
|
||||
| main.rs:12:19:12:60 | res | main.rs:12:27:12:59 | { ... } | provenance | |
|
||||
| main.rs:12:27:12:59 | ...::format(...) | main.rs:12:19:12:60 | res | provenance | |
|
||||
| main.rs:12:27:12:59 | ...::must_use(...) | main.rs:12:9:12:15 | address | provenance | |
|
||||
| main.rs:12:27:12:59 | MacroExpr | main.rs:12:27:12:59 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:12:27:12:59 | { ... } | main.rs:12:27:12:59 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:12:50:12:57 | password | main.rs:12:27:12:59 | MacroExpr | provenance | |
|
||||
| main.rs:13:9:13:11 | url | main.rs:14:28:14:30 | url | provenance | |
|
||||
| main.rs:13:15:13:34 | ...::parse(...) [Ok] | main.rs:13:15:13:43 | ... .unwrap(...) | provenance | MaD:6 |
|
||||
| main.rs:13:15:13:43 | ... .unwrap(...) | main.rs:13:9:13:11 | url | provenance | |
|
||||
| main.rs:13:26:13:33 | &address [&ref] | main.rs:13:15:13:34 | ...::parse(...) [Ok] | provenance | MaD:8 |
|
||||
| main.rs:13:27:13:33 | address | main.rs:13:26:13:33 | &address [&ref] | provenance | |
|
||||
| main.rs:14:28:14:30 | url | main.rs:14:5:14:26 | ...::get | provenance | MaD:4 Sink:MaD:4 |
|
||||
| main.rs:19:9:19:11 | url | main.rs:21:17:21:19 | url | provenance | |
|
||||
| main.rs:19:15:19:58 | res | main.rs:19:23:19:57 | { ... } | provenance | |
|
||||
| main.rs:19:23:19:57 | ...::format(...) | main.rs:19:15:19:58 | res | provenance | |
|
||||
| main.rs:19:23:19:57 | ...::must_use(...) | main.rs:19:9:19:11 | url | provenance | |
|
||||
| main.rs:19:23:19:57 | MacroExpr | main.rs:19:23:19:57 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:19:23:19:57 | { ... } | main.rs:19:23:19:57 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:19:50:19:57 | password | main.rs:19:23:19:57 | MacroExpr | provenance | |
|
||||
| main.rs:21:17:21:19 | url | main.rs:21:12:21:15 | post | provenance | MaD:1 Sink:MaD:1 |
|
||||
| main.rs:26:9:26:11 | url | main.rs:28:33:28:35 | url | provenance | |
|
||||
| main.rs:26:15:26:58 | res | main.rs:26:23:26:57 | { ... } | provenance | |
|
||||
| main.rs:26:23:26:57 | ...::format(...) | main.rs:26:15:26:58 | res | provenance | |
|
||||
| main.rs:26:23:26:57 | ...::must_use(...) | main.rs:26:9:26:11 | url | provenance | |
|
||||
| main.rs:26:23:26:57 | MacroExpr | main.rs:26:23:26:57 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:26:23:26:57 | { ... } | main.rs:26:23:26:57 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:26:50:26:57 | password | main.rs:26:23:26:57 | MacroExpr | provenance | |
|
||||
| main.rs:28:33:28:35 | url | main.rs:28:12:28:18 | request | provenance | MaD:3 Sink:MaD:3 |
|
||||
| main.rs:33:9:33:11 | url | main.rs:35:33:35:35 | url | provenance | |
|
||||
| main.rs:33:15:33:58 | res | main.rs:33:23:33:57 | { ... } | provenance | |
|
||||
| main.rs:33:23:33:57 | ...::format(...) | main.rs:33:15:33:58 | res | provenance | |
|
||||
| main.rs:33:23:33:57 | ...::must_use(...) | main.rs:33:9:33:11 | url | provenance | |
|
||||
| main.rs:33:23:33:57 | MacroExpr | main.rs:33:23:33:57 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:33:23:33:57 | { ... } | main.rs:33:23:33:57 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:33:50:33:57 | password | main.rs:33:23:33:57 | MacroExpr | provenance | |
|
||||
| main.rs:35:33:35:35 | url | main.rs:35:12:35:18 | request | provenance | MaD:2 Sink:MaD:2 |
|
||||
models
|
||||
| 1 | Sink: repo:https://github.com/seanmonstar/reqwest:reqwest; <crate::async_impl::client::Client>::post; transmission; Argument[0] |
|
||||
| 2 | Sink: repo:https://github.com/seanmonstar/reqwest:reqwest; <crate::async_impl::client::Client>::request; transmission; Argument[1] |
|
||||
| 3 | Sink: repo:https://github.com/seanmonstar/reqwest:reqwest; <crate::blocking::client::Client>::request; transmission; Argument[1] |
|
||||
| 4 | Sink: repo:https://github.com/seanmonstar/reqwest:reqwest; crate::blocking::get; transmission; Argument[0] |
|
||||
| 5 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
|
||||
| 6 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value |
|
||||
| 7 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
|
||||
| 8 | Summary: repo:https://github.com/servo/rust-url:url; <crate::Url>::parse; Argument[0].Reference; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
|
||||
nodes
|
||||
| main.rs:6:9:6:11 | url | semmle.label | url |
|
||||
| main.rs:6:15:6:58 | res | semmle.label | res |
|
||||
| main.rs:6:23:6:57 | ...::format(...) | semmle.label | ...::format(...) |
|
||||
| main.rs:6:23:6:57 | ...::must_use(...) | semmle.label | ...::must_use(...) |
|
||||
| main.rs:6:23:6:57 | MacroExpr | semmle.label | MacroExpr |
|
||||
| main.rs:6:23:6:57 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:6:50:6:57 | password | semmle.label | password |
|
||||
| main.rs:7:5:7:26 | ...::get | semmle.label | ...::get |
|
||||
| main.rs:7:28:7:30 | url | semmle.label | url |
|
||||
| main.rs:12:9:12:15 | address | semmle.label | address |
|
||||
| main.rs:12:19:12:60 | res | semmle.label | res |
|
||||
| main.rs:12:27:12:59 | ...::format(...) | semmle.label | ...::format(...) |
|
||||
| main.rs:12:27:12:59 | ...::must_use(...) | semmle.label | ...::must_use(...) |
|
||||
| main.rs:12:27:12:59 | MacroExpr | semmle.label | MacroExpr |
|
||||
| main.rs:12:27:12:59 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:12:50:12:57 | password | semmle.label | password |
|
||||
| main.rs:13:9:13:11 | url | semmle.label | url |
|
||||
| main.rs:13:15:13:34 | ...::parse(...) [Ok] | semmle.label | ...::parse(...) [Ok] |
|
||||
| main.rs:13:15:13:43 | ... .unwrap(...) | semmle.label | ... .unwrap(...) |
|
||||
| main.rs:13:26:13:33 | &address [&ref] | semmle.label | &address [&ref] |
|
||||
| main.rs:13:27:13:33 | address | semmle.label | address |
|
||||
| main.rs:14:5:14:26 | ...::get | semmle.label | ...::get |
|
||||
| main.rs:14:28:14:30 | url | semmle.label | url |
|
||||
| main.rs:19:9:19:11 | url | semmle.label | url |
|
||||
| main.rs:19:15:19:58 | res | semmle.label | res |
|
||||
| main.rs:19:23:19:57 | ...::format(...) | semmle.label | ...::format(...) |
|
||||
| main.rs:19:23:19:57 | ...::must_use(...) | semmle.label | ...::must_use(...) |
|
||||
| main.rs:19:23:19:57 | MacroExpr | semmle.label | MacroExpr |
|
||||
| main.rs:19:23:19:57 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:19:50:19:57 | password | semmle.label | password |
|
||||
| main.rs:21:12:21:15 | post | semmle.label | post |
|
||||
| main.rs:21:17:21:19 | url | semmle.label | url |
|
||||
| main.rs:26:9:26:11 | url | semmle.label | url |
|
||||
| main.rs:26:15:26:58 | res | semmle.label | res |
|
||||
| main.rs:26:23:26:57 | ...::format(...) | semmle.label | ...::format(...) |
|
||||
| main.rs:26:23:26:57 | ...::must_use(...) | semmle.label | ...::must_use(...) |
|
||||
| main.rs:26:23:26:57 | MacroExpr | semmle.label | MacroExpr |
|
||||
| main.rs:26:23:26:57 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:26:50:26:57 | password | semmle.label | password |
|
||||
| main.rs:28:12:28:18 | request | semmle.label | request |
|
||||
| main.rs:28:33:28:35 | url | semmle.label | url |
|
||||
| main.rs:33:9:33:11 | url | semmle.label | url |
|
||||
| main.rs:33:15:33:58 | res | semmle.label | res |
|
||||
| main.rs:33:23:33:57 | ...::format(...) | semmle.label | ...::format(...) |
|
||||
| main.rs:33:23:33:57 | ...::must_use(...) | semmle.label | ...::must_use(...) |
|
||||
| main.rs:33:23:33:57 | MacroExpr | semmle.label | MacroExpr |
|
||||
| main.rs:33:23:33:57 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:33:50:33:57 | password | semmle.label | password |
|
||||
| main.rs:35:12:35:18 | request | semmle.label | request |
|
||||
| main.rs:35:33:35:35 | url | semmle.label | url |
|
||||
subpaths
|
||||
@@ -0,0 +1,4 @@
|
||||
query: queries/security/CWE-311/CleartextTransmission.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
44
rust/ql/test/query-tests/security/CWE-311/main.rs
Normal file
44
rust/ql/test/query-tests/security/CWE-311/main.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use http::Method;
|
||||
use url::Url;
|
||||
|
||||
fn get_with_password_in_url() {
|
||||
let password = "Hunter12";
|
||||
let url = format!("example.com?password={}", password); // $ Source
|
||||
reqwest::blocking::get(url).unwrap().text().unwrap(); // $ Alert[rust/cleartext-transmission]
|
||||
}
|
||||
|
||||
fn get_with_password_in_constructed_url() {
|
||||
let password = "Hunter12";
|
||||
let address = format!("example.com?password={password}"); // $ Source
|
||||
let url = Url::parse(&address).unwrap();
|
||||
reqwest::blocking::get(url).unwrap().text().unwrap(); // $ Alert[rust/cleartext-transmission]
|
||||
}
|
||||
|
||||
fn post_with_password_in_url() {
|
||||
let password = "Hunter12";
|
||||
let url = format!("example.com?password={}", password); // $ Source
|
||||
let client = reqwest::Client::new();
|
||||
client.post(url).body("body").send(); // $ Alert[rust/cleartext-transmission]
|
||||
}
|
||||
|
||||
fn request_blocking_put_with_password_in_url() {
|
||||
let password = "Hunter12";
|
||||
let url = format!("example.com?password={}", password); // $ Source
|
||||
let client = reqwest::blocking::Client::new();
|
||||
client.request(Method::PUT, url).body("body").send(); // $ Alert[rust/cleartext-transmission]
|
||||
}
|
||||
|
||||
fn request_put_with_password_in_url() {
|
||||
let password = "Hunter12";
|
||||
let url = format!("example.com?password={}", password); // $ Source
|
||||
let client = reqwest::Client::new();
|
||||
client.request(Method::PUT, url).body("body").send(); // $ Alert[rust/cleartext-transmission]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
get_with_password_in_url();
|
||||
get_with_password_in_constructed_url();
|
||||
post_with_password_in_url();
|
||||
request_blocking_put_with_password_in_url();
|
||||
request_put_with_password_in_url();
|
||||
}
|
||||
5
rust/ql/test/query-tests/security/CWE-311/options.yml
Normal file
5
rust/ql/test/query-tests/security/CWE-311/options.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
qltest_cargo_check: true
|
||||
qltest_dependencies:
|
||||
- reqwest = { version = "0.12.9", features = ["blocking"] }
|
||||
- http = { version = "1.2.0" }
|
||||
- url = { version = "2.5.4" }
|
||||
Reference in New Issue
Block a user