mirror of https://github.com/astral-sh/ruff
[`flake8-bandit`] Implement `paramiko-call` (`S601`) (#4500)
This commit is contained in:
parent
ab303f4e09
commit
fdb241cad2
|
|
@ -0,0 +1,3 @@
|
||||||
|
import paramiko
|
||||||
|
|
||||||
|
paramiko.exec_command('something; really; unsafe')
|
||||||
|
|
@ -2846,6 +2846,9 @@ where
|
||||||
if self.settings.rules.enabled(Rule::RequestWithoutTimeout) {
|
if self.settings.rules.enabled(Rule::RequestWithoutTimeout) {
|
||||||
flake8_bandit::rules::request_without_timeout(self, func, args, keywords);
|
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
|
if self
|
||||||
.settings
|
.settings
|
||||||
.rules
|
.rules
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||||
(Flake8Bandit, "506") => (RuleGroup::Unspecified, Rule::UnsafeYAMLLoad),
|
(Flake8Bandit, "506") => (RuleGroup::Unspecified, Rule::UnsafeYAMLLoad),
|
||||||
(Flake8Bandit, "508") => (RuleGroup::Unspecified, Rule::SnmpInsecureVersion),
|
(Flake8Bandit, "508") => (RuleGroup::Unspecified, Rule::SnmpInsecureVersion),
|
||||||
(Flake8Bandit, "509") => (RuleGroup::Unspecified, Rule::SnmpWeakCryptography),
|
(Flake8Bandit, "509") => (RuleGroup::Unspecified, Rule::SnmpWeakCryptography),
|
||||||
|
(Flake8Bandit, "601") => (RuleGroup::Unspecified, Rule::ParamikoCall),
|
||||||
(Flake8Bandit, "602") => (RuleGroup::Unspecified, Rule::SubprocessPopenWithShellEqualsTrue),
|
(Flake8Bandit, "602") => (RuleGroup::Unspecified, Rule::SubprocessPopenWithShellEqualsTrue),
|
||||||
(Flake8Bandit, "603") => (RuleGroup::Unspecified, Rule::SubprocessWithoutShellEqualsTrue),
|
(Flake8Bandit, "603") => (RuleGroup::Unspecified, Rule::SubprocessWithoutShellEqualsTrue),
|
||||||
(Flake8Bandit, "604") => (RuleGroup::Unspecified, Rule::CallWithShellEqualsTrue),
|
(Flake8Bandit, "604") => (RuleGroup::Unspecified, Rule::CallWithShellEqualsTrue),
|
||||||
|
|
|
||||||
|
|
@ -422,6 +422,7 @@ ruff_macros::register_rules!(
|
||||||
rules::flake8_bandit::rules::HardcodedTempFile,
|
rules::flake8_bandit::rules::HardcodedTempFile,
|
||||||
rules::flake8_bandit::rules::HashlibInsecureHashFunction,
|
rules::flake8_bandit::rules::HashlibInsecureHashFunction,
|
||||||
rules::flake8_bandit::rules::Jinja2AutoescapeFalse,
|
rules::flake8_bandit::rules::Jinja2AutoescapeFalse,
|
||||||
|
rules::flake8_bandit::rules::ParamikoCall,
|
||||||
rules::flake8_bandit::rules::LoggingConfigInsecureListen,
|
rules::flake8_bandit::rules::LoggingConfigInsecureListen,
|
||||||
rules::flake8_bandit::rules::RequestWithNoCertValidation,
|
rules::flake8_bandit::rules::RequestWithNoCertValidation,
|
||||||
rules::flake8_bandit::rules::RequestWithoutTimeout,
|
rules::flake8_bandit::rules::RequestWithoutTimeout,
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ mod tests {
|
||||||
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"); "S112")]
|
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"); "S112")]
|
||||||
#[test_case(Rule::TryExceptPass, Path::new("S110.py"); "S110")]
|
#[test_case(Rule::TryExceptPass, Path::new("S110.py"); "S110")]
|
||||||
#[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"); "S506")]
|
#[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<()> {
|
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ pub(crate) use jinja2_autoescape_false::{jinja2_autoescape_false, Jinja2Autoesca
|
||||||
pub(crate) use logging_config_insecure_listen::{
|
pub(crate) use logging_config_insecure_listen::{
|
||||||
logging_config_insecure_listen, LoggingConfigInsecureListen,
|
logging_config_insecure_listen, LoggingConfigInsecureListen,
|
||||||
};
|
};
|
||||||
|
pub(crate) use paramiko_calls::{paramiko_call, ParamikoCall};
|
||||||
pub(crate) use request_with_no_cert_validation::{
|
pub(crate) use request_with_no_cert_validation::{
|
||||||
request_with_no_cert_validation, RequestWithNoCertValidation,
|
request_with_no_cert_validation, RequestWithNoCertValidation,
|
||||||
};
|
};
|
||||||
|
|
@ -57,6 +58,7 @@ mod hardcoded_tmp_directory;
|
||||||
mod hashlib_insecure_hash_functions;
|
mod hashlib_insecure_hash_functions;
|
||||||
mod jinja2_autoescape_false;
|
mod jinja2_autoescape_false;
|
||||||
mod logging_config_insecure_listen;
|
mod logging_config_insecure_listen;
|
||||||
|
mod paramiko_calls;
|
||||||
mod request_with_no_cert_validation;
|
mod request_with_no_cert_validation;
|
||||||
mod request_without_timeout;
|
mod request_without_timeout;
|
||||||
mod shell_injection;
|
mod shell_injection;
|
||||||
|
|
|
||||||
|
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2257,6 +2257,7 @@
|
||||||
"S509",
|
"S509",
|
||||||
"S6",
|
"S6",
|
||||||
"S60",
|
"S60",
|
||||||
|
"S601",
|
||||||
"S602",
|
"S602",
|
||||||
"S603",
|
"S603",
|
||||||
"S604",
|
"S604",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue