Skip to content

Commit 1cc3164

Browse files
committed
tokio-postgres-hardcoded-password-rust
1 parent 2b31bbd commit 1cc3164

File tree

3 files changed

+348
-0
lines changed

3 files changed

+348
-0
lines changed
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
id: tokio-postgres-hardcoded-password-rust
2+
language: rust
3+
severity: warning
4+
message: >-
5+
The application uses an empty credential. This can lead to unauthorized
6+
access by either an internal or external malicious actor. It is
7+
recommended to rotate the secret and retrieve them from a secure secret
8+
vault or Hardware Security Module (HSM), alternatively environment
9+
variables can be used if allowed by your company policy.
10+
note: >-
11+
[CWE-287] Improper Authentication.
12+
[REFERENCES]
13+
- https://docs.rs/tokio-postgres/latest/tokio_postgres/
14+
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures
15+
16+
utils:
17+
MATCH_FOLLOW_1:
18+
follows:
19+
stopBy: end
20+
any:
21+
- kind: let_declaration
22+
all:
23+
- has:
24+
kind: identifier
25+
pattern: $CONFIG
26+
- has:
27+
kind: call_expression
28+
regex: ^tokio_postgres::Config::new\(\)$
29+
- kind: let_declaration
30+
all:
31+
- has:
32+
kind: identifier
33+
pattern: $CONFIG
34+
- has:
35+
kind: call_expression
36+
regex: ^Config::new\(\)$
37+
any:
38+
- follows:
39+
stopBy: end
40+
kind: use_declaration
41+
has:
42+
stopBy: end
43+
kind: scoped_identifier
44+
regex: ^tokio_postgres::Config$
45+
- inside:
46+
stopBy: end
47+
follows:
48+
stopBy: end
49+
kind: use_declaration
50+
has:
51+
stopBy: end
52+
kind: scoped_identifier
53+
regex: ^tokio_postgres::Config$
54+
55+
56+
rule:
57+
kind: call_expression
58+
not:
59+
has:
60+
stopBy: end
61+
kind: ERROR
62+
any:
63+
# CONFIG IS DIRECT AND PWD IS DIRECT
64+
- all:
65+
- has:
66+
stopBy: end
67+
kind: scoped_identifier
68+
regex: ^tokio_postgres::Config::new()$
69+
- has:
70+
kind: field_expression
71+
regex: \.password$
72+
nthChild: 1
73+
- has:
74+
kind: arguments
75+
nthChild: 2
76+
has:
77+
stopBy: end
78+
kind: string_literal
79+
has:
80+
kind: string_content
81+
nthChild: 1
82+
all:
83+
- not:
84+
has:
85+
stopBy: end
86+
nthChild: 2
87+
- not:
88+
has:
89+
stopBy: end
90+
any:
91+
- kind: block
92+
- kind: array_expression
93+
# CONFIG IS DIRECT AND PWD IS INSTANCE
94+
- all:
95+
- has:
96+
stopBy: end
97+
kind: scoped_identifier
98+
regex: ^tokio_postgres::Config::new()$
99+
- has:
100+
kind: field_expression
101+
regex: \.password$
102+
nthChild: 1
103+
- has:
104+
kind: arguments
105+
nthChild: 2
106+
has:
107+
stopBy: end
108+
kind: identifier
109+
pattern: $PASSWORD
110+
inside:
111+
stopBy: end
112+
follows:
113+
stopBy: end
114+
any:
115+
- kind: let_declaration
116+
has:
117+
kind: identifier
118+
pattern: $PASSWORD
119+
precedes:
120+
stopBy: end
121+
kind: string_literal
122+
has:
123+
kind: string_content
124+
- kind: expression_statement
125+
has:
126+
kind: assignment_expression
127+
has:
128+
kind: identifier
129+
pattern: $PASSWORD
130+
precedes:
131+
stopBy: end
132+
kind: string_literal
133+
has:
134+
kind: string_content
135+
136+
nthChild: 1
137+
all:
138+
- not:
139+
has:
140+
stopBy: end
141+
nthChild: 2
142+
- not:
143+
has:
144+
stopBy: end
145+
any:
146+
- kind: block
147+
- kind: array_expression
148+
# CONFIG IS INSTANCE AND PWD IS DIRECT
149+
- all:
150+
- has:
151+
stopBy: end
152+
kind: identifier
153+
pattern: $CONFIG
154+
any:
155+
- inside:
156+
stopBy: end
157+
matches: MATCH_FOLLOW_1
158+
- has:
159+
kind: field_expression
160+
regex: \.password$
161+
nthChild: 1
162+
- has:
163+
kind: arguments
164+
nthChild: 2
165+
has:
166+
stopBy: end
167+
kind: string_literal
168+
has:
169+
kind: string_content
170+
nthChild: 1
171+
all:
172+
- not:
173+
has:
174+
stopBy: end
175+
nthChild: 2
176+
- not:
177+
has:
178+
stopBy: end
179+
any:
180+
- kind: block
181+
- kind: array_expression
182+
# CONFIG IS INSTANCE AND PWD IS INSTANCE
183+
- all:
184+
- has:
185+
stopBy: end
186+
kind: identifier
187+
pattern: $CONFIG
188+
any:
189+
- inside:
190+
stopBy: end
191+
matches: MATCH_FOLLOW_1
192+
- has:
193+
kind: field_expression
194+
regex: \.password$
195+
nthChild: 1
196+
- has:
197+
kind: arguments
198+
nthChild: 2
199+
has:
200+
stopBy: end
201+
kind: identifier
202+
pattern: $PASSWORD
203+
nthChild: 1
204+
inside:
205+
stopBy: end
206+
follows:
207+
stopBy: end
208+
any:
209+
- kind: let_declaration
210+
all:
211+
- has:
212+
kind: identifier
213+
pattern: $PASSWORD
214+
- has:
215+
kind: string_literal
216+
has:
217+
kind: string_content
218+
- kind: expression_statement
219+
has:
220+
kind: assignment_expression
221+
all:
222+
- has:
223+
kind: identifier
224+
pattern: $PASSWORD
225+
- has:
226+
kind: string_literal
227+
has:
228+
kind: string_content
229+
230+
all:
231+
- not:
232+
has:
233+
stopBy: end
234+
nthChild: 2
235+
- not:
236+
has:
237+
stopBy: end
238+
any:
239+
- kind: block
240+
- kind: array_expression
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
id: tokio-postgres-hardcoded-password-rust
2+
snapshots:
3+
? |-
4+
async fn okTest2() -> Result<(), anyhow::Error> {
5+
let (client, connection) = tokio_postgres::Config::new()
6+
.host(shard_host_name.as_str())
7+
.user("postgres")
8+
.password("myPassword")
9+
.dbname("ninja")
10+
.keepalives_idle(std::time::Duration::from_secs(30))
11+
.connect(NoTls)
12+
.await
13+
.map_err(|e| {
14+
error!(log, "failed to connect to {}: {}", &shard_host_name, e);
15+
Error::new(ErrorKind::Other, e)
16+
})?;
17+
18+
tokio::spawn(async move {
19+
if let Err(e) = connection.await {
20+
tracing::error!("postgres db connection error: {}", e);
21+
}
22+
});
23+
24+
Ok(())
25+
}
26+
: labels:
27+
- source: |-
28+
tokio_postgres::Config::new()
29+
.host(shard_host_name.as_str())
30+
.user("postgres")
31+
.password("myPassword")
32+
style: primary
33+
start: 79
34+
end: 194
35+
- source: tokio_postgres::Config::new
36+
style: secondary
37+
start: 79
38+
end: 106
39+
- source: |-
40+
tokio_postgres::Config::new()
41+
.host(shard_host_name.as_str())
42+
.user("postgres")
43+
.password
44+
style: secondary
45+
start: 79
46+
end: 180
47+
- source: myPassword
48+
style: secondary
49+
start: 182
50+
end: 192
51+
- source: '"myPassword"'
52+
style: secondary
53+
start: 181
54+
end: 193
55+
- source: ("myPassword")
56+
style: secondary
57+
start: 180
58+
end: 194
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
id: tokio-postgres-hardcoded-password-rust
2+
valid:
3+
- |
4+
async fn okTest2() -> Result<(), anyhow::Error> {
5+
let (client, connection) = tokio_postgres::Config::new()
6+
.host(shard_host_name.as_str())
7+
.user("postgres")
8+
.password("")
9+
.dbname("ninja")
10+
.keepalives_idle(std::time::Duration::from_secs(30))
11+
.connect(NoTls)
12+
.await
13+
.map_err(|e| {
14+
error!(log, "failed to connect to {}: {}", &shard_host_name, e);
15+
Error::new(ErrorKind::Other, e)
16+
})?;
17+
18+
tokio::spawn(async move {
19+
if let Err(e) = connection.await {
20+
tracing::error!("postgres db connection error: {}", e);
21+
}
22+
});
23+
24+
Ok(())
25+
}
26+
27+
invalid:
28+
- |
29+
async fn okTest2() -> Result<(), anyhow::Error> {
30+
let (client, connection) = tokio_postgres::Config::new()
31+
.host(shard_host_name.as_str())
32+
.user("postgres")
33+
.password("myPassword")
34+
.dbname("ninja")
35+
.keepalives_idle(std::time::Duration::from_secs(30))
36+
.connect(NoTls)
37+
.await
38+
.map_err(|e| {
39+
error!(log, "failed to connect to {}: {}", &shard_host_name, e);
40+
Error::new(ErrorKind::Other, e)
41+
})?;
42+
43+
tokio::spawn(async move {
44+
if let Err(e) = connection.await {
45+
tracing::error!("postgres db connection error: {}", e);
46+
}
47+
});
48+
49+
Ok(())
50+
}

0 commit comments

Comments
 (0)