diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S401.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S401.py new file mode 100644 index 0000000000000..1140e955ac39d --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S401.py @@ -0,0 +1,2 @@ +import telnetlib # S401 +from telnetlib import Telnet # S401 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S402.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S402.py new file mode 100644 index 0000000000000..f58a56259bc67 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S402.py @@ -0,0 +1,2 @@ +import ftplib # S402 +from ftplib import FTP # S402 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S403.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S403.py new file mode 100644 index 0000000000000..2aec54eb8c936 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S403.py @@ -0,0 +1,8 @@ +import dill # S403 +from dill import objects # S403 +import shelve +from shelve import open +import cPickle +from cPickle import load +import pickle +from pickle import load diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S404.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S404.py new file mode 100644 index 0000000000000..31de131180f4a --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S404.py @@ -0,0 +1,3 @@ +import subprocess # S404 +from subprocess import Popen # S404 +from subprocess import Popen as pop # S404 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S405.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S405.py new file mode 100644 index 0000000000000..8bf2d4a63b184 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S405.py @@ -0,0 +1,4 @@ +import xml.etree.cElementTree # S405 +from xml.etree import cElementTree # S405 +import xml.etree.ElementTree # S405 +from xml.etree import ElementTree # S405 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S406.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S406.py new file mode 100644 index 0000000000000..698bc6e75ba43 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S406.py @@ -0,0 +1,3 @@ +from xml import sax # S406 +import xml.sax as xmls # S406 +import xml.sax # S406 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S407.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S407.py new file mode 100644 index 0000000000000..e7d3841382f4c --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S407.py @@ -0,0 +1,2 @@ +from xml.dom import expatbuilder # S407 +import xml.dom.expatbuilder # S407 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S408.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S408.py new file mode 100644 index 0000000000000..5fa6fb8e7f5c1 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S408.py @@ -0,0 +1,2 @@ +from xml.dom.minidom import parseString # S408 +import xml.dom.minidom # S408 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S409.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S409.py new file mode 100644 index 0000000000000..fe9ea30d1bf82 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S409.py @@ -0,0 +1,2 @@ +from xml.dom.pulldom import parseString # S409 +import xml.dom.pulldom # S409 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S410.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S410.py new file mode 100644 index 0000000000000..5ff308d53d35a --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S410.py @@ -0,0 +1,2 @@ +import lxml # S410 +from lxml import etree # S410 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S411.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S411.py new file mode 100644 index 0000000000000..b72b6520fbbef --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S411.py @@ -0,0 +1,2 @@ +import xmlrpc # S411 +from xmlrpc import server # S411 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S412.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S412.py new file mode 100644 index 0000000000000..1b8163323ab93 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S412.py @@ -0,0 +1 @@ +from twisted.web.twcgi import CGIScript # S412 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S413.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S413.py new file mode 100644 index 0000000000000..b0ec780ca8033 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S413.py @@ -0,0 +1,4 @@ +import Crypto.Hash # S413 +from Crypto.Hash import MD2 # S413 +import Crypto.PublicKey # S413 +from Crypto.PublicKey import RSA # S413 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S415.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S415.py new file mode 100644 index 0000000000000..4c9a5c267e2aa --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S415.py @@ -0,0 +1,3 @@ +import pyghmi # S415 +from pyghmi import foo # S415 + diff --git a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs index 20ed78c8350f5..4c5360beb250e 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs @@ -552,6 +552,24 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { if checker.enabled(Rule::DeprecatedMockImport) { pyupgrade::rules::deprecated_mock_import(checker, stmt); } + if checker.any_enabled(&[ + Rule::SuspiciousTelnetlibImport, + Rule::SuspiciousFtplibImport, + Rule::SuspiciousPickleImport, + Rule::SuspiciousSubprocessImport, + Rule::SuspiciousXmlEtreeImport, + Rule::SuspiciousXmlSaxImport, + Rule::SuspiciousXmlExpatImport, + Rule::SuspiciousXmlMinidomImport, + Rule::SuspiciousXmlPulldomImport, + Rule::SuspiciousLxmlImport, + Rule::SuspiciousXmlrpcImport, + Rule::SuspiciousHttpoxyImport, + Rule::SuspiciousPycryptoImport, + Rule::SuspiciousPyghmiImport, + ]) { + flake8_bandit::rules::suspicious_imports(checker, stmt); + } for alias in names { if checker.enabled(Rule::NonAsciiImportName) { @@ -751,6 +769,24 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { pyupgrade::rules::unnecessary_builtin_import(checker, stmt, module, names); } } + if checker.any_enabled(&[ + Rule::SuspiciousTelnetlibImport, + Rule::SuspiciousFtplibImport, + Rule::SuspiciousPickleImport, + Rule::SuspiciousSubprocessImport, + Rule::SuspiciousXmlEtreeImport, + Rule::SuspiciousXmlSaxImport, + Rule::SuspiciousXmlExpatImport, + Rule::SuspiciousXmlMinidomImport, + Rule::SuspiciousXmlPulldomImport, + Rule::SuspiciousLxmlImport, + Rule::SuspiciousXmlrpcImport, + Rule::SuspiciousHttpoxyImport, + Rule::SuspiciousPycryptoImport, + Rule::SuspiciousPyghmiImport, + ]) { + flake8_bandit::rules::suspicious_imports(checker, stmt); + } if checker.enabled(Rule::BannedApi) { if let Some(module) = helpers::resolve_imported_module_path(level, module, checker.module_path) diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index f964f7da53fd6..905e249e2af10 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -627,6 +627,20 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Bandit, "321") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousFTPLibUsage), (Flake8Bandit, "323") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage), (Flake8Bandit, "324") => (RuleGroup::Stable, rules::flake8_bandit::rules::HashlibInsecureHashFunction), + (Flake8Bandit, "401") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousTelnetlibImport), + (Flake8Bandit, "402") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousFtplibImport), + (Flake8Bandit, "403") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPickleImport), + (Flake8Bandit, "404") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousSubprocessImport), + (Flake8Bandit, "405") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlEtreeImport), + (Flake8Bandit, "406") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlSaxImport), + (Flake8Bandit, "407") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlExpatImport), + (Flake8Bandit, "408") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlMinidomImport), + (Flake8Bandit, "409") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlPulldomImport), + (Flake8Bandit, "410") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousLxmlImport), + (Flake8Bandit, "411") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlrpcImport), + (Flake8Bandit, "412") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousHttpoxyImport), + (Flake8Bandit, "413") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPycryptoImport), + (Flake8Bandit, "415") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPyghmiImport), (Flake8Bandit, "501") => (RuleGroup::Stable, rules::flake8_bandit::rules::RequestWithNoCertValidation), (Flake8Bandit, "505") => (RuleGroup::Preview, rules::flake8_bandit::rules::WeakCryptographicKey), (Flake8Bandit, "506") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnsafeYAMLLoad), diff --git a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs index ce041669f1782..a27f8b19444d8 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs @@ -45,6 +45,20 @@ mod tests { #[test_case(Rule::SuspiciousEvalUsage, Path::new("S307.py"))] #[test_case(Rule::SuspiciousURLOpenUsage, Path::new("S310.py"))] #[test_case(Rule::SuspiciousTelnetUsage, Path::new("S312.py"))] + #[test_case(Rule::SuspiciousTelnetlibImport, Path::new("S401.py"))] + #[test_case(Rule::SuspiciousFtplibImport, Path::new("S402.py"))] + #[test_case(Rule::SuspiciousPickleImport, Path::new("S403.py"))] + #[test_case(Rule::SuspiciousSubprocessImport, Path::new("S404.py"))] + #[test_case(Rule::SuspiciousXmlEtreeImport, Path::new("S405.py"))] + #[test_case(Rule::SuspiciousXmlSaxImport, Path::new("S406.py"))] + #[test_case(Rule::SuspiciousXmlExpatImport, Path::new("S407.py"))] + #[test_case(Rule::SuspiciousXmlMinidomImport, Path::new("S408.py"))] + #[test_case(Rule::SuspiciousXmlPulldomImport, Path::new("S409.py"))] + #[test_case(Rule::SuspiciousLxmlImport, Path::new("S410.py"))] + #[test_case(Rule::SuspiciousXmlrpcImport, Path::new("S411.py"))] + #[test_case(Rule::SuspiciousHttpoxyImport, Path::new("S412.py"))] + #[test_case(Rule::SuspiciousPycryptoImport, Path::new("S413.py"))] + #[test_case(Rule::SuspiciousPyghmiImport, Path::new("S415.py"))] #[test_case(Rule::TryExceptContinue, Path::new("S112.py"))] #[test_case(Rule::TryExceptPass, Path::new("S110.py"))] #[test_case(Rule::UnixCommandWildcardInjection, Path::new("S609.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs index ee1de347d6152..e33ee02f098c9 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs @@ -21,6 +21,7 @@ pub(crate) use snmp_insecure_version::*; pub(crate) use snmp_weak_cryptography::*; pub(crate) use ssh_no_host_key_verification::*; pub(crate) use suspicious_function_call::*; +pub(crate) use suspicious_imports::*; pub(crate) use tarfile_unsafe_members::*; pub(crate) use try_except_continue::*; pub(crate) use try_except_pass::*; @@ -50,6 +51,7 @@ mod snmp_insecure_version; mod snmp_weak_cryptography; mod ssh_no_host_key_verification; mod suspicious_function_call; +mod suspicious_imports; mod tarfile_unsafe_members; mod try_except_continue; mod try_except_pass; diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_imports.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_imports.rs new file mode 100644 index 0000000000000..e8d8bbed5a7ef --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_imports.rs @@ -0,0 +1,592 @@ +//! Check for imports of or from suspicious modules. +//! +//! See: +use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Stmt}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::registry::AsRule; + +/// ## What it does +/// Checks for imports of the`telnetlib` module. +/// +/// ## Why is this bad? +/// Telnet is considered insecure. Instead, ise SSH or another encrypted +/// protocol. +/// +/// ## Example +/// ```python +/// import telnetlib +/// ``` +#[violation] +pub struct SuspiciousTelnetlibImport; + +impl Violation for SuspiciousTelnetlibImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`telnetlib` and related modules are considered insecure. Use SSH or another encrypted protocol.") + } +} + +/// ## What it does +/// Checks for imports of the `ftplib` module. +/// +/// ## Why is this bad? +/// FTP is considered insecure. Instead, use SSH, SFTP, SCP, or another +/// encrypted protocol. +/// +/// ## Example +/// ```python +/// import ftplib +/// ``` +#[violation] +pub struct SuspiciousFtplibImport; + +impl Violation for SuspiciousFtplibImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`ftplib` and related modules are considered insecure. Use SSH, SFTP, SCP, or another encrypted protocol.") + } +} + +/// ## What it does +/// Checks for imports of the `pickle`, `cPickle`, `dill`, and `shelve` modules. +/// +/// ## Why is this bad? +/// It is possible to construct malicious pickle data which will execute +/// arbitrary code during unpickling. Consider possible security implications +/// associated with these modules. +/// +/// ## Example +/// ```python +/// import pickle +/// ``` +/// /// ## References +/// - [Python Docs](https://docs.python.org/3/library/pickle.html) +#[violation] +pub struct SuspiciousPickleImport; + +impl Violation for SuspiciousPickleImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure") + } +} + +/// ## What it does +/// Checks for imports of the `subprocess` module. +/// +/// ## Why is this bad? +/// It is possible to inject malicious commands into subprocess calls. Consider +/// possible security implications associated with this module. +/// +/// ## Example +/// ```python +/// import subprocess +/// ``` +#[violation] +pub struct SuspiciousSubprocessImport; + +impl Violation for SuspiciousSubprocessImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`subprocess` module is possibly insecure") + } +} + +/// ## What it does +/// Checks for imports of the `xml.etree.cElementTree` and `xml.etree.ElementTree` modules +/// +/// ## Why is this bad? +/// Using various methods from these modules to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package, or make sure `defusedxml.defuse_stdlib()` is +/// called before parsing XML data. +/// +/// ## Example +/// ```python +/// import xml.etree.cElementTree +/// ``` +#[violation] +pub struct SuspiciousXmlEtreeImport; + +impl Violation for SuspiciousXmlEtreeImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`xml.etree` methods are vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the `xml.sax` module. +/// +/// ## Why is this bad? +/// Using various methods from these modules to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package, or make sure `defusedxml.defuse_stdlib()` is +/// called before parsing XML data. +/// +/// ## Example +/// ```python +/// import xml.sax +/// ``` +#[violation] +pub struct SuspiciousXmlSaxImport; + +impl Violation for SuspiciousXmlSaxImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`xml.sax` methods are vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the `xml.dom.expatbuilder` module. +/// +/// ## Why is this bad? +/// Using various methods from these modules to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package, or make sure `defusedxml.defuse_stdlib()` is +/// called before parsing XML data. +/// +/// ## Example +/// ```python +/// import xml.dom.expatbuilder +/// ``` +#[violation] +pub struct SuspiciousXmlExpatImport; + +impl Violation for SuspiciousXmlExpatImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`xml.dom.expatbuilder` is vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the `xml.dom.minidom` module. +/// +/// ## Why is this bad? +/// Using various methods from these modules to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package, or make sure `defusedxml.defuse_stdlib()` is +/// called before parsing XML data. +/// +/// ## Example +/// ```python +/// import xml.dom.minidom +/// ``` +#[violation] +pub struct SuspiciousXmlMinidomImport; + +impl Violation for SuspiciousXmlMinidomImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`xml.dom.minidom` is vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the `xml.dom.pulldom` module. +/// +/// ## Why is this bad? +/// Using various methods from these modules to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package, or make sure `defusedxml.defuse_stdlib()` is +/// called before parsing XML data. +/// +/// ## Example +/// ```python +/// import xml.dom.pulldom +/// ``` +#[violation] +pub struct SuspiciousXmlPulldomImport; + +impl Violation for SuspiciousXmlPulldomImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`xml.dom.pulldom` is vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the`lxml` module. +/// +/// ## Why is this bad? +/// Using various methods from the `lxml` module to parse untrusted XML data is +/// known to be vulnerable to XML attacks. Replace vulnerable imports with the +/// equivalent `defusedxml` package. +/// +/// ## Example +/// ```python +/// import lxml +/// ``` +#[violation] +pub struct SuspiciousLxmlImport; + +impl Violation for SuspiciousLxmlImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`lxml` is vulnerable to XML attacks") + } +} + +/// ## What it does +/// Checks for imports of the `xmlrpc` module. +/// +/// ## Why is this bad? +/// XMLRPC is a particularly dangerous XML module as it is also concerned with +/// communicating data over a network. Use the `defused.xmlrpc.monkey_patch()` +/// function to monkey-patch the `xmlrpclib` module and mitigate remote XML +/// attacks. +/// +/// ## Example +/// ```python +/// import xmlrpc +/// ``` +#[violation] +pub struct SuspiciousXmlrpcImport; + +impl Violation for SuspiciousXmlrpcImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("XMLRPC is vulnerable to remote XML attacks") + } +} + +/// ## What it does +/// Checks for imports of `wsgiref.handlers.CGIHandler` and +/// `twisted.web.twcgi.CGIScript`. +/// +/// ## Why is this bad? +/// httpoxy is a set of vulnerabilities that affect application code running in +/// CGI or CGI-like environments. The use of CGI for web applications should be +/// avoided to prevent this class of attack. +/// +/// ## Example +/// ```python +/// import wsgiref.handlers.CGIHandler +/// ``` +/// +/// ## References +/// - [httpoxy website](https://httpoxy.org/) +#[violation] +pub struct SuspiciousHttpoxyImport; + +impl Violation for SuspiciousHttpoxyImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("`httpoxy` is a set of vulnerabilities that affect application code running inCGI, or CGI-like environments. The use of CGI for web applications should be avoided") + } +} + +/// ## What it does +/// Checks for imports of several unsafe cryptography modules. +/// +/// ## Why is this bad? +/// The `pycrypto` library is known to have a publicly disclosed buffer +/// overflow vulnerability. It is no longer actively maintained and has been +/// deprecated in favor of the `pyca/cryptography` library. +/// +/// ## Example +/// ```python +/// import Crypto.Random +/// ``` +/// +/// ## References +/// - [Buffer Overflow Issue](https://github.com/pycrypto/pycrypto/issues/176) +#[violation] +pub struct SuspiciousPycryptoImport; + +impl Violation for SuspiciousPycryptoImport { + #[derive_message_formats] + fn message(&self) -> String { + format!( + "`pycrypto` library is known to have publicly disclosed buffer overflow vulnerability" + ) + } +} + +/// ## What it does +/// Checks for imports of the `pyghmi` module. +/// +/// ## Why is this bad? +/// `pyghmi` is an IPMI-related module, but IPMI is considered insecure. +/// Instead, use an encrypted protocol. +/// +/// ## Example +/// ```python +/// import pyghmi +/// ``` +/// +/// ## References +/// - [Buffer Overflow Issue](https://github.com/pycrypto/pycrypto/issues/176) +#[violation] +pub struct SuspiciousPyghmiImport; + +impl Violation for SuspiciousPyghmiImport { + #[derive_message_formats] + fn message(&self) -> String { + format!("An IPMI-related module is being imported. Prefer an encrypted protocol over IPMI.") + } +} + +/// S401, S402, S403, S404, S405, S406, S407, S408, S409, S410, S411, S412, S413, S415 +pub(crate) fn suspicious_imports(checker: &mut Checker, stmt: &Stmt) { + match stmt { + Stmt::Import(ast::StmtImport { names, .. }) => { + for name in names { + match name.name.as_str() { + "telnetlib" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousTelnetlibImport), + name.range, + ), + "ftplib" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousFtplibImport), + name.range, + ), + "pickle" | "cPickle" | "dill" | "shelve" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPickleImport), + name.range, + ), + "subprocess" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousSubprocessImport), + name.range, + ), + "xml.etree.cElementTree" | "xml.etree.ElementTree" => { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlEtreeImport), + name.range, + ); + } + "xml.sax" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlSaxImport), + name.range, + ), + "xml.dom.expatbuilder" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlExpatImport), + name.range, + ), + "xml.dom.minidom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlMinidomImport), + name.range, + ), + "xml.dom.pulldom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlPulldomImport), + name.range, + ), + "lxml" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousLxmlImport), + name.range, + ), + "xmlrpc" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlrpcImport), + name.range, + ), + "Crypto.Cipher" | "Crypto.Hash" | "Crypto.IO" | "Crypto.Protocol" + | "Crypto.PublicKey" | "Crypto.Random" | "Crypto.Signature" | "Crypto.Util" => { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPycryptoImport), + name.range, + ); + } + "pyghmi" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPyghmiImport), + name.range, + ), + _ => {} + } + } + } + Stmt::ImportFrom(ast::StmtImportFrom { module, names, .. }) => { + let Some(identifier) = module else { return }; + match identifier.as_str() { + "telnetlib" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousTelnetlibImport), + identifier.range(), + ), + "ftplib" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousFtplibImport), + identifier.range(), + ), + "pickle" | "cPickle" | "dill" | "shelve" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPickleImport), + identifier.range(), + ), + "subprocess" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousSubprocessImport), + identifier.range(), + ), + "xml.etree" => { + for name in names { + if matches!(name.name.as_str(), "cElementTree" | "ElementTree") { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlEtreeImport), + identifier.range(), + ); + } + } + } + "xml.etree.cElementTree" | "xml.etree.ElementTree" => { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlEtreeImport), + identifier.range(), + ); + } + "xml" => { + for name in names { + if name.name.as_str() == "sax" { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlSaxImport), + identifier.range(), + ); + } + } + } + "xml.sax" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlSaxImport), + identifier.range(), + ), + "xml.dom" => { + for name in names { + match name.name.as_str() { + "expatbuilder" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlExpatImport), + identifier.range(), + ), + "minidom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlMinidomImport), + identifier.range(), + ), + "pulldom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlPulldomImport), + identifier.range(), + ), + _ => (), + } + } + } + "xml.dom.expatbuilder" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlExpatImport), + identifier.range(), + ), + "xml.dom.minidom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlMinidomImport), + identifier.range(), + ), + "xml.dom.pulldom" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlPulldomImport), + identifier.range(), + ), + "lxml" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousLxmlImport), + identifier.range(), + ), + "xmlrpc" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousXmlrpcImport), + identifier.range(), + ), + "wsgiref.handlers" => { + for name in names { + if name.name.as_str() == "CGIHandler" { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousHttpoxyImport), + identifier.range(), + ); + } + } + } + "twisted.web.twcgi" => { + for name in names { + if name.name.as_str() == "CGIScript" { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousHttpoxyImport), + identifier.range(), + ); + } + } + } + "Crypto" => { + for name in names { + if matches!( + name.name.as_str(), + "Cipher" + | "Hash" + | "IO" + | "Protocol" + | "PublicKey" + | "Random" + | "Signature" + | "Util" + ) { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPycryptoImport), + identifier.range(), + ); + } + } + } + "Crypto.Cipher" | "Crypto.Hash" | "Crypto.IO" | "Crypto.Protocol" + | "Crypto.PublicKey" | "Crypto.Random" | "Crypto.Signature" | "Crypto.Util" => { + check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPycryptoImport), + identifier.range(), + ); + } + "pyghmi" => check_and_push_diagnostic( + checker, + DiagnosticKind::from(SuspiciousPyghmiImport), + identifier.range(), + ), + _ => {} + } + } + _ => panic!("Expected Stmt::Import | Stmt::ImportFrom"), + }; +} + +fn check_and_push_diagnostic( + checker: &mut Checker, + diagnostic_kind: DiagnosticKind, + range: TextRange, +) { + let diagnostic = Diagnostic::new::(diagnostic_kind, range); + if checker.enabled(diagnostic.kind.rule()) { + checker.diagnostics.push(diagnostic); + } +} diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S401_S401.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S401_S401.py.snap new file mode 100644 index 0000000000000..238e12cb37a0b --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S401_S401.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S401.py:1:8: S401 `telnetlib` and related modules are considered insecure. Use SSH or another encrypted protocol. + | +1 | import telnetlib # S401 + | ^^^^^^^^^ S401 +2 | from telnetlib import Telnet # S401 + | + +S401.py:2:6: S401 `telnetlib` and related modules are considered insecure. Use SSH or another encrypted protocol. + | +1 | import telnetlib # S401 +2 | from telnetlib import Telnet # S401 + | ^^^^^^^^^ S401 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S402_S402.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S402_S402.py.snap new file mode 100644 index 0000000000000..76133c6a5e3f7 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S402_S402.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S402.py:1:8: S402 `ftplib` and related modules are considered insecure. Use SSH, SFTP, SCP, or another encrypted protocol. + | +1 | import ftplib # S402 + | ^^^^^^ S402 +2 | from ftplib import FTP # S402 + | + +S402.py:2:6: S402 `ftplib` and related modules are considered insecure. Use SSH, SFTP, SCP, or another encrypted protocol. + | +1 | import ftplib # S402 +2 | from ftplib import FTP # S402 + | ^^^^^^ S402 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S403_S403.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S403_S403.py.snap new file mode 100644 index 0000000000000..40a790297e356 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S403_S403.py.snap @@ -0,0 +1,78 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S403.py:1:8: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +1 | import dill # S403 + | ^^^^ S403 +2 | from dill import objects # S403 +3 | import shelve + | + +S403.py:2:6: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +1 | import dill # S403 +2 | from dill import objects # S403 + | ^^^^ S403 +3 | import shelve +4 | from shelve import open + | + +S403.py:3:8: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +1 | import dill # S403 +2 | from dill import objects # S403 +3 | import shelve + | ^^^^^^ S403 +4 | from shelve import open +5 | import cPickle + | + +S403.py:4:6: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +2 | from dill import objects # S403 +3 | import shelve +4 | from shelve import open + | ^^^^^^ S403 +5 | import cPickle +6 | from cPickle import load + | + +S403.py:5:8: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +3 | import shelve +4 | from shelve import open +5 | import cPickle + | ^^^^^^^ S403 +6 | from cPickle import load +7 | import pickle + | + +S403.py:6:6: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +4 | from shelve import open +5 | import cPickle +6 | from cPickle import load + | ^^^^^^^ S403 +7 | import pickle +8 | from pickle import load + | + +S403.py:7:8: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +5 | import cPickle +6 | from cPickle import load +7 | import pickle + | ^^^^^^ S403 +8 | from pickle import load + | + +S403.py:8:6: S403 `pickle`, `cPickle`, `dill`, and `shelve` modules are possibly insecure + | +6 | from cPickle import load +7 | import pickle +8 | from pickle import load + | ^^^^^^ S403 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S404_S404.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S404_S404.py.snap new file mode 100644 index 0000000000000..f67e404f427e4 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S404_S404.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S404.py:1:8: S404 `subprocess` module is possibly insecure + | +1 | import subprocess # S404 + | ^^^^^^^^^^ S404 +2 | from subprocess import Popen # S404 +3 | from subprocess import Popen as pop # S404 + | + +S404.py:2:6: S404 `subprocess` module is possibly insecure + | +1 | import subprocess # S404 +2 | from subprocess import Popen # S404 + | ^^^^^^^^^^ S404 +3 | from subprocess import Popen as pop # S404 + | + +S404.py:3:6: S404 `subprocess` module is possibly insecure + | +1 | import subprocess # S404 +2 | from subprocess import Popen # S404 +3 | from subprocess import Popen as pop # S404 + | ^^^^^^^^^^ S404 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S405_S405.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S405_S405.py.snap new file mode 100644 index 0000000000000..9f4f8322c927f --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S405_S405.py.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S405.py:1:8: S405 `xml.etree` methods are vulnerable to XML attacks + | +1 | import xml.etree.cElementTree # S405 + | ^^^^^^^^^^^^^^^^^^^^^^ S405 +2 | from xml.etree import cElementTree # S405 +3 | import xml.etree.ElementTree # S405 + | + +S405.py:2:6: S405 `xml.etree` methods are vulnerable to XML attacks + | +1 | import xml.etree.cElementTree # S405 +2 | from xml.etree import cElementTree # S405 + | ^^^^^^^^^ S405 +3 | import xml.etree.ElementTree # S405 +4 | from xml.etree import ElementTree # S405 + | + +S405.py:3:8: S405 `xml.etree` methods are vulnerable to XML attacks + | +1 | import xml.etree.cElementTree # S405 +2 | from xml.etree import cElementTree # S405 +3 | import xml.etree.ElementTree # S405 + | ^^^^^^^^^^^^^^^^^^^^^ S405 +4 | from xml.etree import ElementTree # S405 + | + +S405.py:4:6: S405 `xml.etree` methods are vulnerable to XML attacks + | +2 | from xml.etree import cElementTree # S405 +3 | import xml.etree.ElementTree # S405 +4 | from xml.etree import ElementTree # S405 + | ^^^^^^^^^ S405 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S406_S406.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S406_S406.py.snap new file mode 100644 index 0000000000000..ef1c448cd3579 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S406_S406.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S406.py:1:6: S406 `xml.sax` methods are vulnerable to XML attacks + | +1 | from xml import sax # S406 + | ^^^ S406 +2 | import xml.sax as xmls # S406 +3 | import xml.sax # S406 + | + +S406.py:2:8: S406 `xml.sax` methods are vulnerable to XML attacks + | +1 | from xml import sax # S406 +2 | import xml.sax as xmls # S406 + | ^^^^^^^^^^^^^^^ S406 +3 | import xml.sax # S406 + | + +S406.py:3:8: S406 `xml.sax` methods are vulnerable to XML attacks + | +1 | from xml import sax # S406 +2 | import xml.sax as xmls # S406 +3 | import xml.sax # S406 + | ^^^^^^^ S406 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S407_S407.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S407_S407.py.snap new file mode 100644 index 0000000000000..91c88345a4f17 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S407_S407.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S407.py:1:6: S407 `xml.dom.expatbuilder` is vulnerable to XML attacks + | +1 | from xml.dom import expatbuilder # S407 + | ^^^^^^^ S407 +2 | import xml.dom.expatbuilder # S407 + | + +S407.py:2:8: S407 `xml.dom.expatbuilder` is vulnerable to XML attacks + | +1 | from xml.dom import expatbuilder # S407 +2 | import xml.dom.expatbuilder # S407 + | ^^^^^^^^^^^^^^^^^^^^ S407 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S408_S408.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S408_S408.py.snap new file mode 100644 index 0000000000000..e42d754a9ec54 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S408_S408.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S408.py:1:6: S408 `xml.dom.minidom` is vulnerable to XML attacks + | +1 | from xml.dom.minidom import parseString # S408 + | ^^^^^^^^^^^^^^^ S408 +2 | import xml.dom.minidom # S408 + | + +S408.py:2:8: S408 `xml.dom.minidom` is vulnerable to XML attacks + | +1 | from xml.dom.minidom import parseString # S408 +2 | import xml.dom.minidom # S408 + | ^^^^^^^^^^^^^^^ S408 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S409_S409.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S409_S409.py.snap new file mode 100644 index 0000000000000..e65eacfe96f9e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S409_S409.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S409.py:1:6: S409 `xml.dom.pulldom` is vulnerable to XML attacks + | +1 | from xml.dom.pulldom import parseString # S409 + | ^^^^^^^^^^^^^^^ S409 +2 | import xml.dom.pulldom # S409 + | + +S409.py:2:8: S409 `xml.dom.pulldom` is vulnerable to XML attacks + | +1 | from xml.dom.pulldom import parseString # S409 +2 | import xml.dom.pulldom # S409 + | ^^^^^^^^^^^^^^^ S409 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S410_S410.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S410_S410.py.snap new file mode 100644 index 0000000000000..56304d26707e0 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S410_S410.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S410.py:1:8: S410 `lxml` is vulnerable to XML attacks + | +1 | import lxml # S410 + | ^^^^ S410 +2 | from lxml import etree # S410 + | + +S410.py:2:6: S410 `lxml` is vulnerable to XML attacks + | +1 | import lxml # S410 +2 | from lxml import etree # S410 + | ^^^^ S410 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S411_S411.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S411_S411.py.snap new file mode 100644 index 0000000000000..0cb05d60b5de0 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S411_S411.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S411.py:1:8: S411 XMLRPC is vulnerable to remote XML attacks + | +1 | import xmlrpc # S411 + | ^^^^^^ S411 +2 | from xmlrpc import server # S411 + | + +S411.py:2:6: S411 XMLRPC is vulnerable to remote XML attacks + | +1 | import xmlrpc # S411 +2 | from xmlrpc import server # S411 + | ^^^^^^ S411 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S412_S412.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S412_S412.py.snap new file mode 100644 index 0000000000000..f6acbda39983f --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S412_S412.py.snap @@ -0,0 +1,10 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S412.py:1:6: S412 `httpoxy` is a set of vulnerabilities that affect application code running inCGI, or CGI-like environments. The use of CGI for web applications should be avoided + | +1 | from twisted.web.twcgi import CGIScript # S412 + | ^^^^^^^^^^^^^^^^^ S412 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S413_S413.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S413_S413.py.snap new file mode 100644 index 0000000000000..fa8676bd2d8a1 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S413_S413.py.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S413.py:1:8: S413 `pycrypto` library is known to have publicly disclosed buffer overflow vulnerability + | +1 | import Crypto.Hash # S413 + | ^^^^^^^^^^^ S413 +2 | from Crypto.Hash import MD2 # S413 +3 | import Crypto.PublicKey # S413 + | + +S413.py:2:6: S413 `pycrypto` library is known to have publicly disclosed buffer overflow vulnerability + | +1 | import Crypto.Hash # S413 +2 | from Crypto.Hash import MD2 # S413 + | ^^^^^^^^^^^ S413 +3 | import Crypto.PublicKey # S413 +4 | from Crypto.PublicKey import RSA # S413 + | + +S413.py:3:8: S413 `pycrypto` library is known to have publicly disclosed buffer overflow vulnerability + | +1 | import Crypto.Hash # S413 +2 | from Crypto.Hash import MD2 # S413 +3 | import Crypto.PublicKey # S413 + | ^^^^^^^^^^^^^^^^ S413 +4 | from Crypto.PublicKey import RSA # S413 + | + +S413.py:4:6: S413 `pycrypto` library is known to have publicly disclosed buffer overflow vulnerability + | +2 | from Crypto.Hash import MD2 # S413 +3 | import Crypto.PublicKey # S413 +4 | from Crypto.PublicKey import RSA # S413 + | ^^^^^^^^^^^^^^^^ S413 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S415_S415.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S415_S415.py.snap new file mode 100644 index 0000000000000..3c47930c4b044 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S415_S415.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S415.py:1:8: S415 An IPMI-related module is being imported. Prefer an encrypted protocol over IPMI. + | +1 | import pyghmi # S415 + | ^^^^^^ S415 +2 | from pyghmi import foo # S415 + | + +S415.py:2:6: S415 An IPMI-related module is being imported. Prefer an encrypted protocol over IPMI. + | +1 | import pyghmi # S415 +2 | from pyghmi import foo # S415 + | ^^^^^^ S415 + | + + diff --git a/ruff.schema.json b/ruff.schema.json index dce12c257b2b2..40d0ecb8ee5dc 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -3492,6 +3492,23 @@ "S321", "S323", "S324", + "S4", + "S40", + "S401", + "S402", + "S403", + "S404", + "S405", + "S406", + "S407", + "S408", + "S409", + "S41", + "S410", + "S411", + "S412", + "S413", + "S415", "S5", "S50", "S501",