[`flake8-bandit`] Implement `paramiko-call` (`S601`) (#4500)

This commit is contained in:
Ville Skyttä 2023-05-19 06:40:50 +03:00 committed by GitHub
parent ab303f4e09
commit fdb241cad2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 0 deletions

View File

@ -0,0 +1,3 @@
import paramiko
paramiko.exec_command('something; really; unsafe')

View File

@ -2846,6 +2846,9 @@ where
if self.settings.rules.enabled(Rule::RequestWithoutTimeout) {
flake8_bandit::rules::request_without_timeout(self, func, args, keywords);
}
if self.settings.rules.enabled(Rule::ParamikoCall) {
flake8_bandit::rules::paramiko_call(self, func);
}
if self
.settings
.rules

View File

@ -507,6 +507,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Flake8Bandit, "506") => (RuleGroup::Unspecified, Rule::UnsafeYAMLLoad),
(Flake8Bandit, "508") => (RuleGroup::Unspecified, Rule::SnmpInsecureVersion),
(Flake8Bandit, "509") => (RuleGroup::Unspecified, Rule::SnmpWeakCryptography),
(Flake8Bandit, "601") => (RuleGroup::Unspecified, Rule::ParamikoCall),
(Flake8Bandit, "602") => (RuleGroup::Unspecified, Rule::SubprocessPopenWithShellEqualsTrue),
(Flake8Bandit, "603") => (RuleGroup::Unspecified, Rule::SubprocessWithoutShellEqualsTrue),
(Flake8Bandit, "604") => (RuleGroup::Unspecified, Rule::CallWithShellEqualsTrue),

View File

@ -422,6 +422,7 @@ ruff_macros::register_rules!(
rules::flake8_bandit::rules::HardcodedTempFile,
rules::flake8_bandit::rules::HashlibInsecureHashFunction,
rules::flake8_bandit::rules::Jinja2AutoescapeFalse,
rules::flake8_bandit::rules::ParamikoCall,
rules::flake8_bandit::rules::LoggingConfigInsecureListen,
rules::flake8_bandit::rules::RequestWithNoCertValidation,
rules::flake8_bandit::rules::RequestWithoutTimeout,

View File

@ -43,6 +43,7 @@ mod tests {
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"); "S112")]
#[test_case(Rule::TryExceptPass, Path::new("S110.py"); "S110")]
#[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"); "S506")]
#[test_case(Rule::ParamikoCall, Path::new("S601.py"); "S601")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
let diagnostics = test_path(

View File

@ -20,6 +20,7 @@ pub(crate) use jinja2_autoescape_false::{jinja2_autoescape_false, Jinja2Autoesca
pub(crate) use logging_config_insecure_listen::{
logging_config_insecure_listen, LoggingConfigInsecureListen,
};
pub(crate) use paramiko_calls::{paramiko_call, ParamikoCall};
pub(crate) use request_with_no_cert_validation::{
request_with_no_cert_validation, RequestWithNoCertValidation,
};
@ -57,6 +58,7 @@ mod hardcoded_tmp_directory;
mod hashlib_insecure_hash_functions;
mod jinja2_autoescape_false;
mod logging_config_insecure_listen;
mod paramiko_calls;
mod request_with_no_cert_validation;
mod request_without_timeout;
mod shell_injection;

View File

@ -0,0 +1,31 @@
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker;
#[violation]
pub struct ParamikoCall;
impl Violation for ParamikoCall {
#[derive_message_formats]
fn message(&self) -> String {
format!("Possible shell injection via Paramiko call; check inputs are properly sanitized")
}
}
/// S601
pub(crate) fn paramiko_call(checker: &mut Checker, func: &Expr) {
if checker
.ctx
.resolve_call_path(func)
.map_or(false, |call_path| {
call_path.as_slice() == ["paramiko", "exec_command"]
})
{
checker
.diagnostics
.push(Diagnostic::new(ParamikoCall, func.range()));
}
}

View File

@ -0,0 +1,12 @@
---
source: crates/ruff/src/rules/flake8_bandit/mod.rs
---
S601.py:3:1: S601 Possible shell injection via Paramiko call; check inputs are properly sanitized
|
3 | import paramiko
4 |
5 | paramiko.exec_command('something; really; unsafe')
| ^^^^^^^^^^^^^^^^^^^^^ S601
|

1
ruff.schema.json generated
View File

@ -2257,6 +2257,7 @@
"S509",
"S6",
"S60",
"S601",
"S602",
"S603",
"S604",