fix(rules): improve S507 detection (#7661)

## Summary

Follow-up on https://github.com/astral-sh/ruff/pull/7528 that improves
detections of mis-usages of policy in `paramiko`.

First commit applies the same fix as in `bandit`
(https://github.com/PyCQA/bandit/pull/1064), as `paramiko` supports
passing both a class and a class instance for the policy in
`set_missing_host_key_policy`
(8e389c7766/paramiko/client.py (L171-L191)).

Second commit improve the detection of `paramiko` import paths that
trigger a violation, as `AutoAddPolicy`, `WarningPolicy` and `SSHClient`
are not only exposed in `paramiko.client`, but also in `paramiko`
(66117732de/paramiko/__init__.py (L121-L164)).

## Test Plan

Snapshot tests.
This commit is contained in:
Mathieu Kniewallner 2023-09-28 23:35:59 +02:00 committed by GitHub
parent 5e75467757
commit cfbebcf354
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 43 deletions

View file

@ -1,5 +1,6 @@
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::map_callable;
use ruff_python_ast::{Expr, ExprAttribute, ExprCall};
use ruff_python_semantic::analyze::typing;
use ruff_text_size::Ranged;
@ -56,13 +57,15 @@ pub(crate) fn ssh_no_host_key_verification(checker: &mut Checker, call: &ExprCal
return;
};
// Detect either, e.g., `paramiko.client.AutoAddPolicy` or `paramiko.client.AutoAddPolicy()`.
if !checker
.semantic()
.resolve_call_path(policy_argument)
.resolve_call_path(map_callable(policy_argument))
.is_some_and(|call_path| {
matches!(
call_path.as_slice(),
["paramiko", "client", "AutoAddPolicy" | "WarningPolicy"]
| ["paramiko", "AutoAddPolicy" | "WarningPolicy"]
)
})
{
@ -70,7 +73,10 @@ pub(crate) fn ssh_no_host_key_verification(checker: &mut Checker, call: &ExprCal
}
if typing::resolve_assignment(value, checker.semantic()).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["paramiko", "client", "SSHClient"])
matches!(
call_path.as_slice(),
["paramiko", "client", "SSHClient"] | ["paramiko", "SSHClient"]
)
}) {
checker.diagnostics.push(Diagnostic::new(
SSHNoHostKeyVerification,

View file

@ -1,62 +1,82 @@
---
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
---
S507.py:13:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
12 | # Errors
13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
|
S507.py:14:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
12 | # Errors
13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
|
S507.py:15:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
14 | # Errors
15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy())
|
S507.py:16:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
14 | # Errors
15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy())
18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
|
S507.py:17:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy())
| ^^^^^^^^^^^^^^^^^^^^^^ S507
18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
|
S507.py:18:40: S507 Paramiko call with policy set to automatically trust the unknown host key
|
16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy())
18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
| ^^^^^^^^^^^^^ S507
16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
|
S507.py:16:47: S507 Paramiko call with policy set to automatically trust the unknown host key
S507.py:19:47: S507 Paramiko call with policy set to automatically trust the unknown host key
|
14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy)
15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy())
18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
|
S507.py:17:47: S507 Paramiko call with policy set to automatically trust the unknown host key
S507.py:20:47: S507 Paramiko call with policy set to automatically trust the unknown host key
|
15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy)
19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
| ^^^^^^^^^^^^^^^^^^^^ S507
18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy)
|
S507.py:18:47: S507 Paramiko call with policy set to automatically trust the unknown host key
S507.py:21:47: S507 Paramiko call with policy set to automatically trust the unknown host key
|
16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy)
20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
| ^^^^^^^^^^^^^ S507
19 |
20 | # Unrelated
22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy)
|
S507.py:22:54: S507 Paramiko call with policy set to automatically trust the unknown host key
|
20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy)
21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy)
22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy)
| ^^^^^^^^^^^^^^^^^^^^^^ S507
23 |
24 | # Unrelated
|