mirror of
				https://github.com/astral-sh/ruff.git
				synced 2025-10-31 12:05:52 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									5e75467757
								
							
						
					
					
						commit
						cfbebcf354
					
				
					 3 changed files with 73 additions and 43 deletions
				
			
		|  | @ -1,7 +1,9 @@ | ||||||
|  | import paramiko | ||||||
| from paramiko import client | from paramiko import client | ||||||
| from paramiko.client import AutoAddPolicy, WarningPolicy | from paramiko.client import AutoAddPolicy, WarningPolicy | ||||||
| 
 | 
 | ||||||
| ssh_client = client.SSHClient() | ssh_client = client.SSHClient() | ||||||
|  | ssh_client_from_paramiko = paramiko.SSHClient() | ||||||
| 
 | 
 | ||||||
| # OK | # OK | ||||||
| ssh_client.set_missing_host_key_policy(policy=foo) | ssh_client.set_missing_host_key_policy(policy=foo) | ||||||
|  | @ -12,10 +14,12 @@ ssh_client.set_missing_host_key_policy(foo) | ||||||
| # Errors | # Errors | ||||||
| ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) | ||||||
| ssh_client.set_missing_host_key_policy(client.WarningPolicy) | ssh_client.set_missing_host_key_policy(client.WarningPolicy) | ||||||
|  | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) | ||||||
| ssh_client.set_missing_host_key_policy(AutoAddPolicy) | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | ||||||
| ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ||||||
| ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ||||||
| ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | ||||||
|  | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) | ||||||
| 
 | 
 | ||||||
| # Unrelated | # Unrelated | ||||||
| set_missing_host_key_policy(client.AutoAddPolicy) | set_missing_host_key_policy(client.AutoAddPolicy) | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| use ruff_diagnostics::{Diagnostic, Violation}; | use ruff_diagnostics::{Diagnostic, Violation}; | ||||||
| use ruff_macros::{derive_message_formats, 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_ast::{Expr, ExprAttribute, ExprCall}; | ||||||
| use ruff_python_semantic::analyze::typing; | use ruff_python_semantic::analyze::typing; | ||||||
| use ruff_text_size::Ranged; | use ruff_text_size::Ranged; | ||||||
|  | @ -56,13 +57,15 @@ pub(crate) fn ssh_no_host_key_verification(checker: &mut Checker, call: &ExprCal | ||||||
|         return; |         return; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     // Detect either, e.g., `paramiko.client.AutoAddPolicy` or `paramiko.client.AutoAddPolicy()`.
 | ||||||
|     if !checker |     if !checker | ||||||
|         .semantic() |         .semantic() | ||||||
|         .resolve_call_path(policy_argument) |         .resolve_call_path(map_callable(policy_argument)) | ||||||
|         .is_some_and(|call_path| { |         .is_some_and(|call_path| { | ||||||
|             matches!( |             matches!( | ||||||
|                 call_path.as_slice(), |                 call_path.as_slice(), | ||||||
|                 ["paramiko", "client", "AutoAddPolicy" | "WarningPolicy"] |                 ["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| { |     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( |         checker.diagnostics.push(Diagnostic::new( | ||||||
|             SSHNoHostKeyVerification, |             SSHNoHostKeyVerification, | ||||||
|  |  | ||||||
|  | @ -1,62 +1,82 @@ | ||||||
| --- | --- | ||||||
| source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs | 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 | 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 | # Errors | ||||||
| 14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) | 15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) | ||||||
| 15 | ssh_client.set_missing_host_key_policy(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 |    |                                        ^^^^^^^^^^^^^ S507 | ||||||
| 16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | 19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ||||||
| 17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | 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) | 17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) | ||||||
| 15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | 18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | ||||||
| 16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | 19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ||||||
|    |                                               ^^^^^^^^^^^^^^^^^^^^ S507 |    |                                               ^^^^^^^^^^^^^^^^^^^^ S507 | ||||||
| 17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | 20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ||||||
| 18 | ssh_client.set_missing_host_key_policy(policy=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) | 18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | ||||||
| 16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | 19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ||||||
| 17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | 20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ||||||
|    |                                               ^^^^^^^^^^^^^^^^^^^^ S507 |    |                                               ^^^^^^^^^^^^^^^^^^^^ 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) | 19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ||||||
| 17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | 20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ||||||
| 18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | 21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | ||||||
|    |                                               ^^^^^^^^^^^^^ S507 |    |                                               ^^^^^^^^^^^^^ S507 | ||||||
| 19 |  | 22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) | ||||||
| 20 | # Unrelated |    | | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|    | |    | | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mathieu Kniewallner
						Mathieu Kniewallner