mirror of https://github.com/astral-sh/ruff
Add `flake8-bandit` (#697)
This commit is contained in:
parent
da051624e4
commit
1b422a7f12
15
README.md
15
README.md
|
|
@ -467,6 +467,19 @@ For more, see [pep8-naming](https://pypi.org/project/pep8-naming/0.13.2/) on PyP
|
|||
| N817 | CamelcaseImportedAsAcronym | Camelcase `...` imported as acronym `...` | |
|
||||
| N818 | ErrorSuffixOnExceptionName | Exception name `...` should be named with an Error suffix | |
|
||||
|
||||
### flake8-bandit
|
||||
|
||||
For more, see [flake8-bandit](https://pypi.org/project/flake8-bandit/4.1.1/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| S101 | AssertUsed | Use of `assert` detected | |
|
||||
| S102 | ExecUsed | Use of `exec` detected | |
|
||||
| S104 | HardcodedBindAllInterfaces | Possible binding to all interfaces | |
|
||||
| S105 | HardcodedPasswordString | Possible hardcoded password: `'...'` | |
|
||||
| S106 | HardcodedPasswordFuncArg | Possible hardcoded password: `'...'` | |
|
||||
| S107 | HardcodedPasswordDefault | Possible hardcoded password: `'...'` | |
|
||||
|
||||
### flake8-comprehensions
|
||||
|
||||
For more, see [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/3.10.1/) on PyPI.
|
||||
|
|
@ -686,6 +699,7 @@ including:
|
|||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||
- [`flake8-annotations`](https://pypi.org/project/flake8-annotations/)
|
||||
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/)
|
||||
- [`flake8-bandit`](https://pypi.org/project/flake8-bandit/) (6/40)
|
||||
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (21/32)
|
||||
- [`flake8-2020`](https://pypi.org/project/flake8-2020/)
|
||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (15/34)
|
||||
|
|
@ -709,6 +723,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
|||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||
- [`flake8-annotations`](https://pypi.org/project/flake8-annotations/)
|
||||
- [`flake8-bandit`](https://pypi.org/project/flake8-bandit/) (6/40)
|
||||
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/)
|
||||
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (21/32)
|
||||
- [`flake8-2020`](https://pypi.org/project/flake8-2020/)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
# Error
|
||||
assert True
|
||||
|
||||
def fn():
|
||||
x = 1
|
||||
|
||||
# Error
|
||||
assert x == 1
|
||||
|
||||
# Error
|
||||
assert x == 2
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
def fn():
|
||||
# Error
|
||||
exec('x = 2')
|
||||
|
||||
exec('y = 3')
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
def func(address):
|
||||
print(address)
|
||||
|
||||
|
||||
# OK
|
||||
"OK"
|
||||
|
||||
# Error
|
||||
"0.0.0.0"
|
||||
'0.0.0.0'
|
||||
|
||||
|
||||
# Error
|
||||
func("0.0.0.0")
|
||||
|
||||
|
||||
def my_func():
|
||||
x = "0.0.0.0"
|
||||
print(x)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
d = {}
|
||||
|
||||
# OK
|
||||
safe = "s3cr3t"
|
||||
password = True
|
||||
password = safe
|
||||
password is True
|
||||
password == 1
|
||||
d["safe"] = "s3cr3t"
|
||||
|
||||
# Errors
|
||||
password = "s3cr3t"
|
||||
_pass = "s3cr3t"
|
||||
passwd = "s3cr3t"
|
||||
pwd = "s3cr3t"
|
||||
secret = "s3cr3t"
|
||||
token = "s3cr3t"
|
||||
secrete = "s3cr3t"
|
||||
safe = password = "s3cr3t"
|
||||
password = safe = "s3cr3t"
|
||||
|
||||
d["password"] = "s3cr3t"
|
||||
d["pass"] = "s3cr3t"
|
||||
d["passwd"] = "s3cr3t"
|
||||
d["pwd"] = "s3cr3t"
|
||||
d["secret"] = "s3cr3t"
|
||||
d["token"] = "s3cr3t"
|
||||
d["secrete"] = "s3cr3t"
|
||||
safe = d["password"] = "s3cr3t"
|
||||
d["password"] = safe = "s3cr3t"
|
||||
|
||||
|
||||
class MyClass:
|
||||
password = "s3cr3t"
|
||||
safe = password
|
||||
|
||||
|
||||
MyClass.password = "s3cr3t"
|
||||
MyClass._pass = "s3cr3t"
|
||||
MyClass.passwd = "s3cr3t"
|
||||
MyClass.pwd = "s3cr3t"
|
||||
MyClass.secret = "s3cr3t"
|
||||
MyClass.token = "s3cr3t"
|
||||
MyClass.secrete = "s3cr3t"
|
||||
|
||||
password == "s3cr3t"
|
||||
_pass == "s3cr3t"
|
||||
passwd == "s3cr3t"
|
||||
pwd == "s3cr3t"
|
||||
secret == "s3cr3t"
|
||||
token == "s3cr3t"
|
||||
secrete == "s3cr3t"
|
||||
password == safe == "s3cr3t"
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
def func(pos, password):
|
||||
pass
|
||||
|
||||
|
||||
string = "Hello World"
|
||||
|
||||
# OK
|
||||
func("s3cr3t")
|
||||
func(1, password=string)
|
||||
func(pos="s3cr3t", password=string)
|
||||
|
||||
# Error
|
||||
func(1, password="s3cr3t")
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
def ok(first, default="default"):
|
||||
pass
|
||||
|
||||
|
||||
def default(first, password="default"):
|
||||
pass
|
||||
|
||||
|
||||
def ok_posonly(first, /, pos, default="posonly"):
|
||||
pass
|
||||
|
||||
|
||||
def default_posonly(first, /, pos, password="posonly"):
|
||||
pass
|
||||
|
||||
|
||||
def ok_kwonly(first, *, default="kwonly"):
|
||||
pass
|
||||
|
||||
|
||||
def default_kwonly(first, *, password="kwonly"):
|
||||
pass
|
||||
|
||||
|
||||
def ok_all(first, /, pos, default="posonly", *, kwonly="kwonly"):
|
||||
pass
|
||||
|
||||
|
||||
def default_all(first, /, pos, secret="posonly", *, password="kwonly"):
|
||||
pass
|
||||
|
|
@ -32,7 +32,7 @@ use crate::settings::Settings;
|
|||
use crate::source_code_locator::SourceCodeLocator;
|
||||
use crate::visibility::{module_visibility, transition_scope, Modifier, Visibility, VisibleScope};
|
||||
use crate::{
|
||||
docstrings, flake8_2020, flake8_annotations, flake8_bugbear, flake8_builtins,
|
||||
docstrings, flake8_2020, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_print, pep8_naming, pycodestyle, pydocstyle, pyflakes, pyupgrade,
|
||||
};
|
||||
|
||||
|
|
@ -350,6 +350,12 @@ where
|
|||
flake8_bugbear::plugins::cached_instance_method(self, decorator_list);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::S107) {
|
||||
self.add_checks(
|
||||
flake8_bandit::plugins::hardcoded_password_default(args).into_iter(),
|
||||
);
|
||||
}
|
||||
|
||||
self.check_builtin_shadowing(name, Range::from_located(stmt), true);
|
||||
|
||||
// Visit the decorators and arguments, but avoid the body, which will be
|
||||
|
|
@ -803,6 +809,9 @@ where
|
|||
if self.settings.enabled.contains(&CheckCode::B011) {
|
||||
flake8_bugbear::plugins::assert_false(self, stmt, test, msg);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S101) {
|
||||
self.add_check(flake8_bandit::plugins::assert_used(stmt));
|
||||
}
|
||||
}
|
||||
StmtKind::With { items, .. } | StmtKind::AsyncWith { items, .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::B017) {
|
||||
|
|
@ -843,6 +852,13 @@ where
|
|||
if self.settings.enabled.contains(&CheckCode::B003) {
|
||||
flake8_bugbear::plugins::assignment_to_os_environ(self, targets);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S105) {
|
||||
if let Some(check) =
|
||||
flake8_bandit::plugins::assign_hardcoded_password_string(value, targets)
|
||||
{
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
StmtKind::AnnAssign { value, .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::E731) {
|
||||
|
|
@ -1108,6 +1124,16 @@ where
|
|||
self, args, keywords,
|
||||
);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S102) {
|
||||
if let Some(check) = flake8_bandit::plugins::exec_used(expr, func) {
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S106) {
|
||||
self.add_checks(
|
||||
flake8_bandit::plugins::hardcoded_password_func_arg(keywords).into_iter(),
|
||||
);
|
||||
}
|
||||
|
||||
// flake8-comprehensions
|
||||
if self.settings.enabled.contains(&CheckCode::C400) {
|
||||
|
|
@ -1456,6 +1482,16 @@ where
|
|||
{
|
||||
flake8_2020::plugins::compare(self, left, ops, comparators);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::S105) {
|
||||
self.add_checks(
|
||||
flake8_bandit::plugins::compare_to_hardcoded_password_string(
|
||||
left,
|
||||
comparators,
|
||||
)
|
||||
.into_iter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
|
|
@ -1465,6 +1501,14 @@ where
|
|||
self.deferred_string_annotations
|
||||
.push((Range::from_located(expr), value));
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S104) {
|
||||
if let Some(check) = flake8_bandit::plugins::hardcoded_bind_all_interfaces(
|
||||
value,
|
||||
&Range::from_located(expr),
|
||||
) {
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Lambda { args, .. } => {
|
||||
// Visit the arguments, but avoid the body, which will be deferred.
|
||||
|
|
|
|||
|
|
@ -220,6 +220,13 @@ pub enum CheckCode {
|
|||
N818,
|
||||
// isort
|
||||
I001,
|
||||
// flake8-bandit
|
||||
S101,
|
||||
S102,
|
||||
S104,
|
||||
S105,
|
||||
S106,
|
||||
S107,
|
||||
// Ruff
|
||||
RUF001,
|
||||
RUF002,
|
||||
|
|
@ -236,6 +243,7 @@ pub enum CheckCategory {
|
|||
Pydocstyle,
|
||||
Pyupgrade,
|
||||
PEP8Naming,
|
||||
Flake8Bandit,
|
||||
Flake8Comprehensions,
|
||||
Flake8Bugbear,
|
||||
Flake8Builtins,
|
||||
|
|
@ -253,6 +261,7 @@ impl CheckCategory {
|
|||
CheckCategory::Pycodestyle => "pycodestyle",
|
||||
CheckCategory::Pyflakes => "Pyflakes",
|
||||
CheckCategory::Isort => "isort",
|
||||
CheckCategory::Flake8Bandit => "flake8-bandit",
|
||||
CheckCategory::Flake8Builtins => "flake8-builtins",
|
||||
CheckCategory::Flake8Bugbear => "flake8-bugbear",
|
||||
CheckCategory::Flake8Comprehensions => "flake8-comprehensions",
|
||||
|
|
@ -291,6 +300,7 @@ impl CheckCategory {
|
|||
CheckCategory::Pyupgrade => Some("https://pypi.org/project/pyupgrade/3.2.0/"),
|
||||
CheckCategory::Pydocstyle => Some("https://pypi.org/project/pydocstyle/6.1.1/"),
|
||||
CheckCategory::PEP8Naming => Some("https://pypi.org/project/pep8-naming/0.13.2/"),
|
||||
CheckCategory::Flake8Bandit => Some("https://pypi.org/project/flake8-bandit/4.1.1/"),
|
||||
CheckCategory::Ruff => None,
|
||||
CheckCategory::Meta => None,
|
||||
}
|
||||
|
|
@ -509,6 +519,13 @@ pub enum CheckKind {
|
|||
ErrorSuffixOnExceptionName(String),
|
||||
// isort
|
||||
UnsortedImports,
|
||||
// flake8-bandit
|
||||
AssertUsed,
|
||||
ExecUsed,
|
||||
HardcodedBindAllInterfaces,
|
||||
HardcodedPasswordString(String),
|
||||
HardcodedPasswordFuncArg(String),
|
||||
HardcodedPasswordDefault(String),
|
||||
// Ruff
|
||||
AmbiguousUnicodeCharacterString(char, char),
|
||||
AmbiguousUnicodeCharacterDocstring(char, char),
|
||||
|
|
@ -773,6 +790,13 @@ impl CheckCode {
|
|||
CheckCode::N818 => CheckKind::ErrorSuffixOnExceptionName("...".to_string()),
|
||||
// isort
|
||||
CheckCode::I001 => CheckKind::UnsortedImports,
|
||||
// flake8-bandit
|
||||
CheckCode::S101 => CheckKind::AssertUsed,
|
||||
CheckCode::S102 => CheckKind::ExecUsed,
|
||||
CheckCode::S104 => CheckKind::HardcodedBindAllInterfaces,
|
||||
CheckCode::S105 => CheckKind::HardcodedPasswordString("...".to_string()),
|
||||
CheckCode::S106 => CheckKind::HardcodedPasswordFuncArg("...".to_string()),
|
||||
CheckCode::S107 => CheckKind::HardcodedPasswordDefault("...".to_string()),
|
||||
// Ruff
|
||||
CheckCode::RUF001 => CheckKind::AmbiguousUnicodeCharacterString('𝐁', 'B'),
|
||||
CheckCode::RUF002 => CheckKind::AmbiguousUnicodeCharacterDocstring('𝐁', 'B'),
|
||||
|
|
@ -965,6 +989,12 @@ impl CheckCode {
|
|||
CheckCode::N817 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N818 => CheckCategory::PEP8Naming,
|
||||
CheckCode::I001 => CheckCategory::Isort,
|
||||
CheckCode::S101 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S102 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S104 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S105 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S106 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S107 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::RUF001 => CheckCategory::Ruff,
|
||||
CheckCode::RUF002 => CheckCategory::Ruff,
|
||||
CheckCode::RUF003 => CheckCategory::Ruff,
|
||||
|
|
@ -1171,6 +1201,13 @@ impl CheckKind {
|
|||
CheckKind::ErrorSuffixOnExceptionName(..) => &CheckCode::N818,
|
||||
// isort
|
||||
CheckKind::UnsortedImports => &CheckCode::I001,
|
||||
// flake8-bandit
|
||||
CheckKind::AssertUsed => &CheckCode::S101,
|
||||
CheckKind::ExecUsed => &CheckCode::S102,
|
||||
CheckKind::HardcodedBindAllInterfaces => &CheckCode::S104,
|
||||
CheckKind::HardcodedPasswordString(..) => &CheckCode::S105,
|
||||
CheckKind::HardcodedPasswordFuncArg(..) => &CheckCode::S106,
|
||||
CheckKind::HardcodedPasswordDefault(..) => &CheckCode::S107,
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(..) => &CheckCode::RUF001,
|
||||
CheckKind::AmbiguousUnicodeCharacterDocstring(..) => &CheckCode::RUF002,
|
||||
|
|
@ -1778,6 +1815,21 @@ impl CheckKind {
|
|||
}
|
||||
// isort
|
||||
CheckKind::UnsortedImports => "Import block is un-sorted or un-formatted".to_string(),
|
||||
// flake8-bandit
|
||||
CheckKind::AssertUsed => "Use of `assert` detected".to_string(),
|
||||
CheckKind::ExecUsed => "Use of `exec` detected".to_string(),
|
||||
CheckKind::HardcodedBindAllInterfaces => {
|
||||
"Possible binding to all interfaces".to_string()
|
||||
}
|
||||
CheckKind::HardcodedPasswordString(string) => {
|
||||
format!("Possible hardcoded password: `'{string}'`")
|
||||
}
|
||||
CheckKind::HardcodedPasswordFuncArg(string) => {
|
||||
format!("Possible hardcoded password: `'{string}'`")
|
||||
}
|
||||
CheckKind::HardcodedPasswordDefault(string) => {
|
||||
format!("Possible hardcoded password: `'{string}'`")
|
||||
}
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(confusable, representant) => {
|
||||
format!(
|
||||
|
|
|
|||
|
|
@ -245,6 +245,15 @@ pub enum CheckCodePrefix {
|
|||
RUF001,
|
||||
RUF002,
|
||||
RUF003,
|
||||
S,
|
||||
S1,
|
||||
S10,
|
||||
S101,
|
||||
S102,
|
||||
S104,
|
||||
S105,
|
||||
S106,
|
||||
S107,
|
||||
T,
|
||||
T2,
|
||||
T20,
|
||||
|
|
@ -988,6 +997,36 @@ impl CheckCodePrefix {
|
|||
CheckCodePrefix::RUF001 => vec![CheckCode::RUF001],
|
||||
CheckCodePrefix::RUF002 => vec![CheckCode::RUF002],
|
||||
CheckCodePrefix::RUF003 => vec![CheckCode::RUF003],
|
||||
CheckCodePrefix::S => vec![
|
||||
CheckCode::S101,
|
||||
CheckCode::S102,
|
||||
CheckCode::S104,
|
||||
CheckCode::S105,
|
||||
CheckCode::S106,
|
||||
CheckCode::S107,
|
||||
],
|
||||
CheckCodePrefix::S1 => vec![
|
||||
CheckCode::S101,
|
||||
CheckCode::S102,
|
||||
CheckCode::S104,
|
||||
CheckCode::S105,
|
||||
CheckCode::S106,
|
||||
CheckCode::S107,
|
||||
],
|
||||
CheckCodePrefix::S10 => vec![
|
||||
CheckCode::S101,
|
||||
CheckCode::S102,
|
||||
CheckCode::S104,
|
||||
CheckCode::S105,
|
||||
CheckCode::S106,
|
||||
CheckCode::S107,
|
||||
],
|
||||
CheckCodePrefix::S101 => vec![CheckCode::S101],
|
||||
CheckCodePrefix::S102 => vec![CheckCode::S102],
|
||||
CheckCodePrefix::S104 => vec![CheckCode::S104],
|
||||
CheckCodePrefix::S105 => vec![CheckCode::S105],
|
||||
CheckCodePrefix::S106 => vec![CheckCode::S106],
|
||||
CheckCodePrefix::S107 => vec![CheckCode::S107],
|
||||
CheckCodePrefix::T => vec![CheckCode::T201, CheckCode::T203],
|
||||
CheckCodePrefix::T2 => vec![CheckCode::T201, CheckCode::T203],
|
||||
CheckCodePrefix::T20 => vec![CheckCode::T201, CheckCode::T203],
|
||||
|
|
@ -1299,6 +1338,15 @@ impl CheckCodePrefix {
|
|||
CheckCodePrefix::I0 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::I00 => PrefixSpecificity::Tens,
|
||||
CheckCodePrefix::I001 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S => PrefixSpecificity::Category,
|
||||
CheckCodePrefix::S1 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::S10 => PrefixSpecificity::Tens,
|
||||
CheckCodePrefix::S101 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S102 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S104 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S105 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S106 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S107 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::M => PrefixSpecificity::Category,
|
||||
CheckCodePrefix::M0 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::M00 => PrefixSpecificity::Tens,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
use rustpython_ast::{Constant, Expr, ExprKind};
|
||||
|
||||
const PASSWORD_NAMES: [&str; 7] = [
|
||||
"password", "pass", "passwd", "pwd", "secret", "token", "secrete",
|
||||
];
|
||||
|
||||
pub fn string_literal(expr: &Expr) -> Option<&str> {
|
||||
match &expr.node {
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => Some(string),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe use regex for this?
|
||||
pub fn matches_password_name(string: &str) -> bool {
|
||||
PASSWORD_NAMES
|
||||
.iter()
|
||||
.any(|name| string.to_lowercase().contains(name))
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod helpers;
|
||||
pub mod plugins;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use rustpython_ast::{Located, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// S101
|
||||
pub fn assert_used(stmt: &Located<StmtKind>) -> Check {
|
||||
Check::new(CheckKind::AssertUsed, Range::from_located(stmt))
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// S102
|
||||
pub fn exec_used(expr: &Expr, func: &Expr) -> Option<Check> {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id == "exec" {
|
||||
return Some(Check::new(CheckKind::ExecUsed, Range::from_located(expr)));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// S104
|
||||
pub fn hardcoded_bind_all_interfaces(value: &str, range: &Range) -> Option<Check> {
|
||||
if value == "0.0.0.0" {
|
||||
Some(Check::new(CheckKind::HardcodedBindAllInterfaces, *range))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
use rustpython_ast::{ArgData, Arguments, Expr, Located};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::flake8_bandit::helpers::{matches_password_name, string_literal};
|
||||
|
||||
fn check_password_kwarg(arg: &Located<ArgData>, default: &Expr) -> Option<Check> {
|
||||
if let Some(string) = string_literal(default) {
|
||||
let kwarg_name = &arg.node.arg;
|
||||
if matches_password_name(kwarg_name) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordDefault(string.to_string()),
|
||||
Range::from_located(default),
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// S107
|
||||
pub fn hardcoded_password_default(arguments: &Arguments) -> Vec<Check> {
|
||||
let mut checks: Vec<Check> = Vec::new();
|
||||
|
||||
let defaults_start =
|
||||
arguments.posonlyargs.len() + arguments.args.len() - arguments.defaults.len();
|
||||
for (i, arg) in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&arguments.args)
|
||||
.enumerate()
|
||||
{
|
||||
if let Some(i) = i.checked_sub(defaults_start) {
|
||||
let default = &arguments.defaults[i];
|
||||
if let Some(check) = check_password_kwarg(arg, default) {
|
||||
checks.push(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let defaults_start = arguments.kwonlyargs.len() - arguments.kw_defaults.len();
|
||||
for (i, kwarg) in arguments.kwonlyargs.iter().enumerate() {
|
||||
if let Some(i) = i.checked_sub(defaults_start) {
|
||||
let default = &arguments.kw_defaults[i];
|
||||
if let Some(check) = check_password_kwarg(kwarg, default) {
|
||||
checks.push(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checks
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
use rustpython_ast::Keyword;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::flake8_bandit::helpers::{matches_password_name, string_literal};
|
||||
|
||||
/// S106
|
||||
pub fn hardcoded_password_func_arg(keywords: &[Keyword]) -> Vec<Check> {
|
||||
keywords
|
||||
.iter()
|
||||
.filter_map(|keyword| {
|
||||
if let Some(string) = string_literal(&keyword.node.value) {
|
||||
if let Some(arg) = &keyword.node.arg {
|
||||
if matches_password_name(arg) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordFuncArg(string.to_string()),
|
||||
Range::from_located(keyword),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
use rustpython_ast::{Constant, Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::flake8_bandit::helpers::{matches_password_name, string_literal};
|
||||
|
||||
fn is_password_target(target: &Expr) -> bool {
|
||||
let target_name = match &target.node {
|
||||
// variable = "s3cr3t"
|
||||
ExprKind::Name { id, .. } => id,
|
||||
// d["password"] = "s3cr3t"
|
||||
ExprKind::Subscript { slice, .. } => match &slice.node {
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => string,
|
||||
_ => return false,
|
||||
},
|
||||
// obj.password = "s3cr3t"
|
||||
ExprKind::Attribute { attr, .. } => attr,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
matches_password_name(target_name)
|
||||
}
|
||||
|
||||
/// S105
|
||||
pub fn compare_to_hardcoded_password_string(left: &Expr, comparators: &[Expr]) -> Vec<Check> {
|
||||
comparators
|
||||
.iter()
|
||||
.filter_map(|comp| {
|
||||
if let Some(string) = string_literal(comp) {
|
||||
if is_password_target(left) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordString(string.to_string()),
|
||||
Range::from_located(comp),
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// S105
|
||||
pub fn assign_hardcoded_password_string(value: &Expr, targets: &Vec<Expr>) -> Option<Check> {
|
||||
if let Some(string) = string_literal(value) {
|
||||
for target in targets {
|
||||
if is_password_target(target) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordString(string.to_string()),
|
||||
Range::from_located(value),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
pub use assert_used::assert_used;
|
||||
pub use exec_used::exec_used;
|
||||
pub use hardcoded_bind_all_interfaces::hardcoded_bind_all_interfaces;
|
||||
pub use hardcoded_password_default::hardcoded_password_default;
|
||||
pub use hardcoded_password_func_arg::hardcoded_password_func_arg;
|
||||
pub use hardcoded_password_string::{
|
||||
assign_hardcoded_password_string, compare_to_hardcoded_password_string,
|
||||
};
|
||||
|
||||
mod assert_used;
|
||||
mod exec_used;
|
||||
mod hardcoded_bind_all_interfaces;
|
||||
mod hardcoded_password_default;
|
||||
mod hardcoded_password_func_arg;
|
||||
mod hardcoded_password_string;
|
||||
|
|
@ -29,6 +29,7 @@ mod directives;
|
|||
mod docstrings;
|
||||
mod flake8_2020;
|
||||
pub mod flake8_annotations;
|
||||
pub mod flake8_bandit;
|
||||
mod flake8_bugbear;
|
||||
mod flake8_builtins;
|
||||
mod flake8_comprehensions;
|
||||
|
|
|
|||
|
|
@ -469,6 +469,12 @@ mod tests {
|
|||
#[test_case(CheckCode::N816, Path::new("N816.py"); "N816")]
|
||||
#[test_case(CheckCode::N817, Path::new("N817.py"); "N817")]
|
||||
#[test_case(CheckCode::N818, Path::new("N818.py"); "N818")]
|
||||
#[test_case(CheckCode::S101, Path::new("S101.py"); "S101")]
|
||||
#[test_case(CheckCode::S102, Path::new("S102.py"); "S102")]
|
||||
#[test_case(CheckCode::S104, Path::new("S104.py"); "S104")]
|
||||
#[test_case(CheckCode::S105, Path::new("S105.py"); "S105")]
|
||||
#[test_case(CheckCode::S106, Path::new("S106.py"); "S106")]
|
||||
#[test_case(CheckCode::S107, Path::new("S107.py"); "S107")]
|
||||
#[test_case(CheckCode::T201, Path::new("T201.py"); "T201")]
|
||||
#[test_case(CheckCode::T203, Path::new("T203.py"); "T203")]
|
||||
#[test_case(CheckCode::U001, Path::new("U001.py"); "U001")]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: AssertUsed
|
||||
location:
|
||||
row: 2
|
||||
column: 0
|
||||
end_location:
|
||||
row: 2
|
||||
column: 11
|
||||
fix: ~
|
||||
- kind: AssertUsed
|
||||
location:
|
||||
row: 8
|
||||
column: 4
|
||||
end_location:
|
||||
row: 8
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind: AssertUsed
|
||||
location:
|
||||
row: 11
|
||||
column: 4
|
||||
end_location:
|
||||
row: 11
|
||||
column: 17
|
||||
fix: ~
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ExecUsed
|
||||
location:
|
||||
row: 3
|
||||
column: 4
|
||||
end_location:
|
||||
row: 3
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind: ExecUsed
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
end_location:
|
||||
row: 5
|
||||
column: 13
|
||||
fix: ~
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: HardcodedBindAllInterfaces
|
||||
location:
|
||||
row: 9
|
||||
column: 0
|
||||
end_location:
|
||||
row: 9
|
||||
column: 9
|
||||
fix: ~
|
||||
- kind: HardcodedBindAllInterfaces
|
||||
location:
|
||||
row: 10
|
||||
column: 0
|
||||
end_location:
|
||||
row: 10
|
||||
column: 9
|
||||
fix: ~
|
||||
- kind: HardcodedBindAllInterfaces
|
||||
location:
|
||||
row: 14
|
||||
column: 5
|
||||
end_location:
|
||||
row: 14
|
||||
column: 14
|
||||
fix: ~
|
||||
- kind: HardcodedBindAllInterfaces
|
||||
location:
|
||||
row: 18
|
||||
column: 8
|
||||
end_location:
|
||||
row: 18
|
||||
column: 17
|
||||
fix: ~
|
||||
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 12
|
||||
column: 11
|
||||
end_location:
|
||||
row: 12
|
||||
column: 19
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 13
|
||||
column: 8
|
||||
end_location:
|
||||
row: 13
|
||||
column: 16
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 14
|
||||
column: 9
|
||||
end_location:
|
||||
row: 14
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 15
|
||||
column: 6
|
||||
end_location:
|
||||
row: 15
|
||||
column: 14
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 16
|
||||
column: 9
|
||||
end_location:
|
||||
row: 16
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 17
|
||||
column: 8
|
||||
end_location:
|
||||
row: 17
|
||||
column: 16
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 18
|
||||
column: 10
|
||||
end_location:
|
||||
row: 18
|
||||
column: 18
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 19
|
||||
column: 18
|
||||
end_location:
|
||||
row: 19
|
||||
column: 26
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 20
|
||||
column: 18
|
||||
end_location:
|
||||
row: 20
|
||||
column: 26
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 22
|
||||
column: 16
|
||||
end_location:
|
||||
row: 22
|
||||
column: 24
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 23
|
||||
column: 12
|
||||
end_location:
|
||||
row: 23
|
||||
column: 20
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 24
|
||||
column: 14
|
||||
end_location:
|
||||
row: 24
|
||||
column: 22
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 25
|
||||
column: 11
|
||||
end_location:
|
||||
row: 25
|
||||
column: 19
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 26
|
||||
column: 14
|
||||
end_location:
|
||||
row: 26
|
||||
column: 22
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 27
|
||||
column: 13
|
||||
end_location:
|
||||
row: 27
|
||||
column: 21
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 28
|
||||
column: 15
|
||||
end_location:
|
||||
row: 28
|
||||
column: 23
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 29
|
||||
column: 23
|
||||
end_location:
|
||||
row: 29
|
||||
column: 31
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 30
|
||||
column: 23
|
||||
end_location:
|
||||
row: 30
|
||||
column: 31
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 34
|
||||
column: 15
|
||||
end_location:
|
||||
row: 34
|
||||
column: 23
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 38
|
||||
column: 19
|
||||
end_location:
|
||||
row: 38
|
||||
column: 27
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 39
|
||||
column: 16
|
||||
end_location:
|
||||
row: 39
|
||||
column: 24
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 40
|
||||
column: 17
|
||||
end_location:
|
||||
row: 40
|
||||
column: 25
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 41
|
||||
column: 14
|
||||
end_location:
|
||||
row: 41
|
||||
column: 22
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 42
|
||||
column: 17
|
||||
end_location:
|
||||
row: 42
|
||||
column: 25
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 43
|
||||
column: 16
|
||||
end_location:
|
||||
row: 43
|
||||
column: 24
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 44
|
||||
column: 18
|
||||
end_location:
|
||||
row: 44
|
||||
column: 26
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 46
|
||||
column: 12
|
||||
end_location:
|
||||
row: 46
|
||||
column: 20
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 47
|
||||
column: 9
|
||||
end_location:
|
||||
row: 47
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 48
|
||||
column: 10
|
||||
end_location:
|
||||
row: 48
|
||||
column: 18
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 49
|
||||
column: 7
|
||||
end_location:
|
||||
row: 49
|
||||
column: 15
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 50
|
||||
column: 10
|
||||
end_location:
|
||||
row: 50
|
||||
column: 18
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 51
|
||||
column: 9
|
||||
end_location:
|
||||
row: 51
|
||||
column: 17
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 52
|
||||
column: 11
|
||||
end_location:
|
||||
row: 52
|
||||
column: 19
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordString: s3cr3t
|
||||
location:
|
||||
row: 53
|
||||
column: 20
|
||||
end_location:
|
||||
row: 53
|
||||
column: 28
|
||||
fix: ~
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind:
|
||||
HardcodedPasswordFuncArg: s3cr3t
|
||||
location:
|
||||
row: 13
|
||||
column: 8
|
||||
end_location:
|
||||
row: 13
|
||||
column: 25
|
||||
fix: ~
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind:
|
||||
HardcodedPasswordDefault: default
|
||||
location:
|
||||
row: 5
|
||||
column: 28
|
||||
end_location:
|
||||
row: 5
|
||||
column: 37
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordDefault: posonly
|
||||
location:
|
||||
row: 13
|
||||
column: 44
|
||||
end_location:
|
||||
row: 13
|
||||
column: 53
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordDefault: kwonly
|
||||
location:
|
||||
row: 21
|
||||
column: 38
|
||||
end_location:
|
||||
row: 21
|
||||
column: 46
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordDefault: posonly
|
||||
location:
|
||||
row: 29
|
||||
column: 38
|
||||
end_location:
|
||||
row: 29
|
||||
column: 47
|
||||
fix: ~
|
||||
- kind:
|
||||
HardcodedPasswordDefault: kwonly
|
||||
location:
|
||||
row: 29
|
||||
column: 61
|
||||
end_location:
|
||||
row: 29
|
||||
column: 69
|
||||
fix: ~
|
||||
|
||||
Loading…
Reference in New Issue