Skip to content

Commit 5c93a52

Browse files
authored
[flake8-bandit] Implement S4XX suspicious import rules (#8831)
## Summary Adds all `S4XX` rules to the [flake8-bandit](https://github.com/tylerwince/flake8-bandit) plugin port. There is a lot of documentation to write, some tests can be expanded and implementation can probably be refactored to be more compact. As there is some discussion on whether this is actually useful. (See: #1646 (comment)), wanted to check which rules we want to have before I go through the process of polishing this up. ## Test Plan Fixtures for all rules based on `flake8-bandit` [tests](https://github.com/tylerwince/flake8-bandit/tree/main/tests) ## Issue link Refers: #1646
1 parent e3ad163 commit 5c93a52

34 files changed

+1079
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import telnetlib # S401
2+
from telnetlib import Telnet # S401
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import ftplib # S402
2+
from ftplib import FTP # S402
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import dill # S403
2+
from dill import objects # S403
3+
import shelve
4+
from shelve import open
5+
import cPickle
6+
from cPickle import load
7+
import pickle
8+
from pickle import load
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import subprocess # S404
2+
from subprocess import Popen # S404
3+
from subprocess import Popen as pop # S404
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import xml.etree.cElementTree # S405
2+
from xml.etree import cElementTree # S405
3+
import xml.etree.ElementTree # S405
4+
from xml.etree import ElementTree # S405
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from xml import sax # S406
2+
import xml.sax as xmls # S406
3+
import xml.sax # S406
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from xml.dom import expatbuilder # S407
2+
import xml.dom.expatbuilder # S407
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from xml.dom.minidom import parseString # S408
2+
import xml.dom.minidom # S408
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from xml.dom.pulldom import parseString # S409
2+
import xml.dom.pulldom # S409
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import lxml # S410
2+
from lxml import etree # S410
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import xmlrpc # S411
2+
from xmlrpc import server # S411
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from twisted.web.twcgi import CGIScript # S412
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Crypto.Hash # S413
2+
from Crypto.Hash import MD2 # S413
3+
import Crypto.PublicKey # S413
4+
from Crypto.PublicKey import RSA # S413
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import pyghmi # S415
2+
from pyghmi import foo # S415
3+

crates/ruff_linter/src/checkers/ast/analyze/statement.rs

+36
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,24 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
552552
if checker.enabled(Rule::DeprecatedMockImport) {
553553
pyupgrade::rules::deprecated_mock_import(checker, stmt);
554554
}
555+
if checker.any_enabled(&[
556+
Rule::SuspiciousTelnetlibImport,
557+
Rule::SuspiciousFtplibImport,
558+
Rule::SuspiciousPickleImport,
559+
Rule::SuspiciousSubprocessImport,
560+
Rule::SuspiciousXmlEtreeImport,
561+
Rule::SuspiciousXmlSaxImport,
562+
Rule::SuspiciousXmlExpatImport,
563+
Rule::SuspiciousXmlMinidomImport,
564+
Rule::SuspiciousXmlPulldomImport,
565+
Rule::SuspiciousLxmlImport,
566+
Rule::SuspiciousXmlrpcImport,
567+
Rule::SuspiciousHttpoxyImport,
568+
Rule::SuspiciousPycryptoImport,
569+
Rule::SuspiciousPyghmiImport,
570+
]) {
571+
flake8_bandit::rules::suspicious_imports(checker, stmt);
572+
}
555573

556574
for alias in names {
557575
if checker.enabled(Rule::NonAsciiImportName) {
@@ -751,6 +769,24 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
751769
pyupgrade::rules::unnecessary_builtin_import(checker, stmt, module, names);
752770
}
753771
}
772+
if checker.any_enabled(&[
773+
Rule::SuspiciousTelnetlibImport,
774+
Rule::SuspiciousFtplibImport,
775+
Rule::SuspiciousPickleImport,
776+
Rule::SuspiciousSubprocessImport,
777+
Rule::SuspiciousXmlEtreeImport,
778+
Rule::SuspiciousXmlSaxImport,
779+
Rule::SuspiciousXmlExpatImport,
780+
Rule::SuspiciousXmlMinidomImport,
781+
Rule::SuspiciousXmlPulldomImport,
782+
Rule::SuspiciousLxmlImport,
783+
Rule::SuspiciousXmlrpcImport,
784+
Rule::SuspiciousHttpoxyImport,
785+
Rule::SuspiciousPycryptoImport,
786+
Rule::SuspiciousPyghmiImport,
787+
]) {
788+
flake8_bandit::rules::suspicious_imports(checker, stmt);
789+
}
754790
if checker.enabled(Rule::BannedApi) {
755791
if let Some(module) =
756792
helpers::resolve_imported_module_path(level, module, checker.module_path)

crates/ruff_linter/src/codes.rs

+14
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,20 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
627627
(Flake8Bandit, "321") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousFTPLibUsage),
628628
(Flake8Bandit, "323") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage),
629629
(Flake8Bandit, "324") => (RuleGroup::Stable, rules::flake8_bandit::rules::HashlibInsecureHashFunction),
630+
(Flake8Bandit, "401") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousTelnetlibImport),
631+
(Flake8Bandit, "402") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousFtplibImport),
632+
(Flake8Bandit, "403") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPickleImport),
633+
(Flake8Bandit, "404") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousSubprocessImport),
634+
(Flake8Bandit, "405") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlEtreeImport),
635+
(Flake8Bandit, "406") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlSaxImport),
636+
(Flake8Bandit, "407") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlExpatImport),
637+
(Flake8Bandit, "408") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlMinidomImport),
638+
(Flake8Bandit, "409") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlPulldomImport),
639+
(Flake8Bandit, "410") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousLxmlImport),
640+
(Flake8Bandit, "411") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousXmlrpcImport),
641+
(Flake8Bandit, "412") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousHttpoxyImport),
642+
(Flake8Bandit, "413") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPycryptoImport),
643+
(Flake8Bandit, "415") => (RuleGroup::Preview, rules::flake8_bandit::rules::SuspiciousPyghmiImport),
630644
(Flake8Bandit, "501") => (RuleGroup::Stable, rules::flake8_bandit::rules::RequestWithNoCertValidation),
631645
(Flake8Bandit, "505") => (RuleGroup::Preview, rules::flake8_bandit::rules::WeakCryptographicKey),
632646
(Flake8Bandit, "506") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnsafeYAMLLoad),

crates/ruff_linter/src/rules/flake8_bandit/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@ mod tests {
4545
#[test_case(Rule::SuspiciousEvalUsage, Path::new("S307.py"))]
4646
#[test_case(Rule::SuspiciousURLOpenUsage, Path::new("S310.py"))]
4747
#[test_case(Rule::SuspiciousTelnetUsage, Path::new("S312.py"))]
48+
#[test_case(Rule::SuspiciousTelnetlibImport, Path::new("S401.py"))]
49+
#[test_case(Rule::SuspiciousFtplibImport, Path::new("S402.py"))]
50+
#[test_case(Rule::SuspiciousPickleImport, Path::new("S403.py"))]
51+
#[test_case(Rule::SuspiciousSubprocessImport, Path::new("S404.py"))]
52+
#[test_case(Rule::SuspiciousXmlEtreeImport, Path::new("S405.py"))]
53+
#[test_case(Rule::SuspiciousXmlSaxImport, Path::new("S406.py"))]
54+
#[test_case(Rule::SuspiciousXmlExpatImport, Path::new("S407.py"))]
55+
#[test_case(Rule::SuspiciousXmlMinidomImport, Path::new("S408.py"))]
56+
#[test_case(Rule::SuspiciousXmlPulldomImport, Path::new("S409.py"))]
57+
#[test_case(Rule::SuspiciousLxmlImport, Path::new("S410.py"))]
58+
#[test_case(Rule::SuspiciousXmlrpcImport, Path::new("S411.py"))]
59+
#[test_case(Rule::SuspiciousHttpoxyImport, Path::new("S412.py"))]
60+
#[test_case(Rule::SuspiciousPycryptoImport, Path::new("S413.py"))]
61+
#[test_case(Rule::SuspiciousPyghmiImport, Path::new("S415.py"))]
4862
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"))]
4963
#[test_case(Rule::TryExceptPass, Path::new("S110.py"))]
5064
#[test_case(Rule::UnixCommandWildcardInjection, Path::new("S609.py"))]

crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(crate) use snmp_insecure_version::*;
2121
pub(crate) use snmp_weak_cryptography::*;
2222
pub(crate) use ssh_no_host_key_verification::*;
2323
pub(crate) use suspicious_function_call::*;
24+
pub(crate) use suspicious_imports::*;
2425
pub(crate) use tarfile_unsafe_members::*;
2526
pub(crate) use try_except_continue::*;
2627
pub(crate) use try_except_pass::*;
@@ -50,6 +51,7 @@ mod snmp_insecure_version;
5051
mod snmp_weak_cryptography;
5152
mod ssh_no_host_key_verification;
5253
mod suspicious_function_call;
54+
mod suspicious_imports;
5355
mod tarfile_unsafe_members;
5456
mod try_except_continue;
5557
mod try_except_pass;

0 commit comments

Comments
 (0)