Skip to content

Commit

Permalink
Implement S601, paramiko_calls
Browse files Browse the repository at this point in the history
  • Loading branch information
scop committed May 18, 2023
1 parent fdd8941 commit 9d36959
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 0 deletions.
3 changes: 3 additions & 0 deletions crates/ruff/resources/test/fixtures/flake8_bandit/S601.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import paramiko

paramiko.exec_command('something; really; unsafe')
4 changes: 4 additions & 0 deletions crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2846,6 +2846,10 @@ where
if self.settings.rules.enabled(Rule::RequestWithoutTimeout) {
flake8_bandit::rules::request_without_timeout(self, func, args, keywords);
}
if self.settings.rules.enabled(Rule::ParamikoCalls)
{
flake8_bandit::rules::paramiko_calls(self, func);
}
if self
.settings
.rules
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::ParamikoCalls),
(Flake8Bandit, "602") => (RuleGroup::Unspecified, Rule::SubprocessPopenWithShellEqualsTrue),
(Flake8Bandit, "603") => (RuleGroup::Unspecified, Rule::SubprocessWithoutShellEqualsTrue),
(Flake8Bandit, "604") => (RuleGroup::Unspecified, Rule::CallWithShellEqualsTrue),
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::ParamikoCalls,
rules::flake8_bandit::rules::LoggingConfigInsecureListen,
rules::flake8_bandit::rules::RequestWithNoCertValidation,
rules::flake8_bandit::rules::RequestWithoutTimeout,
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/rules/flake8_bandit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::ParamikoCalls, 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(
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff/src/rules/flake8_bandit/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_calls, ParamikoCalls};
pub(crate) use request_with_no_cert_validation::{
request_with_no_cert_validation, RequestWithNoCertValidation,
};
Expand Down Expand Up @@ -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;
Expand Down
34 changes: 34 additions & 0 deletions crates/ruff/src/rules/flake8_bandit/rules/paramiko_calls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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 ParamikoCalls;

impl Violation for ParamikoCalls {
#[derive_message_formats]
fn message(&self) -> String {
format!("Possible shell injection via Paramiko call, check inputs are properly sanitized")
}
}

/// S601
pub(crate) fn paramiko_calls(
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(ParamikoCalls, func.range()));
}
}
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9d36959

Please sign in to comment.