mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Move flake8-bandit violations (#2525)
This commit is contained in:
parent
c96ba6dec4
commit
81b60cf9fe
19 changed files with 324 additions and 293 deletions
|
@ -327,23 +327,23 @@ ruff_macros::define_rule_mapping!(
|
|||
// eradicate
|
||||
ERA001 => rules::eradicate::rules::CommentedOutCode,
|
||||
// flake8-bandit
|
||||
S101 => violations::AssertUsed,
|
||||
S102 => violations::ExecUsed,
|
||||
S103 => violations::BadFilePermissions,
|
||||
S104 => violations::HardcodedBindAllInterfaces,
|
||||
S105 => violations::HardcodedPasswordString,
|
||||
S106 => violations::HardcodedPasswordFuncArg,
|
||||
S107 => violations::HardcodedPasswordDefault,
|
||||
S108 => violations::HardcodedTempFile,
|
||||
S101 => rules::flake8_bandit::rules::AssertUsed,
|
||||
S102 => rules::flake8_bandit::rules::ExecUsed,
|
||||
S103 => rules::flake8_bandit::rules::BadFilePermissions,
|
||||
S104 => rules::flake8_bandit::rules::HardcodedBindAllInterfaces,
|
||||
S105 => rules::flake8_bandit::rules::HardcodedPasswordString,
|
||||
S106 => rules::flake8_bandit::rules::HardcodedPasswordFuncArg,
|
||||
S107 => rules::flake8_bandit::rules::HardcodedPasswordDefault,
|
||||
S108 => rules::flake8_bandit::rules::HardcodedTempFile,
|
||||
S110 => rules::flake8_bandit::rules::TryExceptPass,
|
||||
S113 => violations::RequestWithoutTimeout,
|
||||
S324 => violations::HashlibInsecureHashFunction,
|
||||
S501 => violations::RequestWithNoCertValidation,
|
||||
S506 => violations::UnsafeYAMLLoad,
|
||||
S508 => violations::SnmpInsecureVersion,
|
||||
S509 => violations::SnmpWeakCryptography,
|
||||
S113 => rules::flake8_bandit::rules::RequestWithoutTimeout,
|
||||
S324 => rules::flake8_bandit::rules::HashlibInsecureHashFunction,
|
||||
S501 => rules::flake8_bandit::rules::RequestWithNoCertValidation,
|
||||
S506 => rules::flake8_bandit::rules::UnsafeYAMLLoad,
|
||||
S508 => rules::flake8_bandit::rules::SnmpInsecureVersion,
|
||||
S509 => rules::flake8_bandit::rules::SnmpWeakCryptography,
|
||||
S612 => rules::flake8_bandit::rules::LoggingConfigInsecureListen,
|
||||
S701 => violations::Jinja2AutoescapeFalse,
|
||||
S701 => rules::flake8_bandit::rules::Jinja2AutoescapeFalse,
|
||||
// flake8-boolean-trap
|
||||
FBT001 => rules::flake8_boolean_trap::rules::BooleanPositionalArgInFunctionDefinition,
|
||||
FBT002 => rules::flake8_boolean_trap::rules::BooleanDefaultValueInFunctionDefinition,
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Located, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct AssertUsed;
|
||||
);
|
||||
impl Violation for AssertUsed {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use of `assert` detected")
|
||||
}
|
||||
}
|
||||
|
||||
/// S101
|
||||
pub fn assert_used(stmt: &Located<StmtKind>) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
violations::AssertUsed,
|
||||
AssertUsed,
|
||||
Range::new(stmt.location, stmt.location.with_col_offset("assert".len())),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use num_traits::ToPrimitive;
|
||||
use once_cell::sync::Lazy;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword, Operator};
|
||||
|
||||
|
@ -7,7 +10,19 @@ use crate::ast::helpers::{compose_call_path, SimpleCallArgs};
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct BadFilePermissions {
|
||||
pub mask: u16,
|
||||
}
|
||||
);
|
||||
impl Violation for BadFilePermissions {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let BadFilePermissions { mask } = self;
|
||||
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory",)
|
||||
}
|
||||
}
|
||||
|
||||
const WRITE_WORLD: u16 = 0o2;
|
||||
const EXECUTE_GROUP: u16 = 0o10;
|
||||
|
@ -101,7 +116,7 @@ pub fn bad_file_permissions(
|
|||
if let Some(int_value) = get_int_value(mode_arg) {
|
||||
if (int_value & WRITE_WORLD > 0) || (int_value & EXECUTE_GROUP > 0) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::BadFilePermissions { mask: int_value },
|
||||
BadFilePermissions { mask: int_value },
|
||||
Range::from_located(mode_arg),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct ExecUsed;
|
||||
);
|
||||
impl Violation for ExecUsed {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use of `exec` detected")
|
||||
}
|
||||
}
|
||||
|
||||
/// S102
|
||||
pub fn exec_used(expr: &Expr, func: &Expr) -> Option<Diagnostic> {
|
||||
|
@ -12,8 +24,5 @@ pub fn exec_used(expr: &Expr, func: &Expr) -> Option<Diagnostic> {
|
|||
if id != "exec" {
|
||||
return None;
|
||||
}
|
||||
Some(Diagnostic::new(
|
||||
violations::ExecUsed,
|
||||
Range::from_located(expr),
|
||||
))
|
||||
Some(Diagnostic::new(ExecUsed, Range::from_located(expr)))
|
||||
}
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
use crate::violation::Violation;
|
||||
|
||||
use crate::define_violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedBindAllInterfaces;
|
||||
);
|
||||
impl Violation for HardcodedBindAllInterfaces {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Possible binding to all interfaces")
|
||||
}
|
||||
}
|
||||
|
||||
/// S104
|
||||
pub fn hardcoded_bind_all_interfaces(value: &str, range: &Range) -> Option<Diagnostic> {
|
||||
if value == "0.0.0.0" {
|
||||
Some(Diagnostic::new(
|
||||
violations::HardcodedBindAllInterfaces,
|
||||
*range,
|
||||
))
|
||||
Some(Diagnostic::new(HardcodedBindAllInterfaces, *range))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{ArgData, Arguments, Expr, Located};
|
||||
|
||||
use super::super::helpers::{matches_password_name, string_literal};
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordDefault {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordDefault {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordDefault { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
fn check_password_kwarg(arg: &Located<ArgData>, default: &Expr) -> Option<Diagnostic> {
|
||||
let string = string_literal(default).filter(|string| !string.is_empty())?;
|
||||
|
@ -12,7 +27,7 @@ fn check_password_kwarg(arg: &Located<ArgData>, default: &Expr) -> Option<Diagno
|
|||
return None;
|
||||
}
|
||||
Some(Diagnostic::new(
|
||||
violations::HardcodedPasswordDefault {
|
||||
HardcodedPasswordDefault {
|
||||
string: string.to_string(),
|
||||
},
|
||||
Range::from_located(default),
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Keyword;
|
||||
|
||||
use super::super::helpers::{matches_password_name, string_literal};
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordFuncArg {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordFuncArg {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordFuncArg { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
/// S106
|
||||
pub fn hardcoded_password_func_arg(keywords: &[Keyword]) -> Vec<Diagnostic> {
|
||||
|
@ -16,7 +31,7 @@ pub fn hardcoded_password_func_arg(keywords: &[Keyword]) -> Vec<Diagnostic> {
|
|||
return None;
|
||||
}
|
||||
Some(Diagnostic::new(
|
||||
violations::HardcodedPasswordFuncArg {
|
||||
HardcodedPasswordFuncArg {
|
||||
string: string.to_string(),
|
||||
},
|
||||
Range::from_located(keyword),
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprKind};
|
||||
|
||||
use super::super::helpers::{matches_password_name, string_literal};
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordString {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordString {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordString { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_password_target(target: &Expr) -> bool {
|
||||
let target_name = match &target.node {
|
||||
|
@ -35,7 +50,7 @@ pub fn compare_to_hardcoded_password_string(left: &Expr, comparators: &[Expr]) -
|
|||
return None;
|
||||
}
|
||||
Some(Diagnostic::new(
|
||||
violations::HardcodedPasswordString {
|
||||
HardcodedPasswordString {
|
||||
string: string.to_string(),
|
||||
},
|
||||
Range::from_located(comp),
|
||||
|
@ -50,7 +65,7 @@ pub fn assign_hardcoded_password_string(value: &Expr, targets: &[Expr]) -> Optio
|
|||
for target in targets {
|
||||
if is_password_target(target) {
|
||||
return Some(Diagnostic::new(
|
||||
violations::HardcodedPasswordString {
|
||||
HardcodedPasswordString {
|
||||
string: string.to_string(),
|
||||
},
|
||||
Range::from_located(value),
|
||||
|
|
|
@ -1,8 +1,26 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedTempFile {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedTempFile {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedTempFile { string } = self;
|
||||
format!(
|
||||
"Probable insecure usage of temporary file or directory: \"{}\"",
|
||||
string.escape_debug()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// S108
|
||||
pub fn hardcoded_tmp_directory(
|
||||
|
@ -12,7 +30,7 @@ pub fn hardcoded_tmp_directory(
|
|||
) -> Option<Diagnostic> {
|
||||
if prefixes.iter().any(|prefix| value.starts_with(prefix)) {
|
||||
Some(Diagnostic::new(
|
||||
violations::HardcodedTempFile {
|
||||
HardcodedTempFile {
|
||||
string: value.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use super::super::helpers::string_literal;
|
||||
|
@ -5,7 +8,22 @@ use crate::ast::helpers::SimpleCallArgs;
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct HashlibInsecureHashFunction {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HashlibInsecureHashFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HashlibInsecureHashFunction { string } = self;
|
||||
format!(
|
||||
"Probable use of insecure hash functions in `hashlib`: \"{}\"",
|
||||
string.escape_debug()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const WEAK_HASHES: [&str; 4] = ["md4", "md5", "sha", "sha1"];
|
||||
|
||||
|
@ -56,7 +74,7 @@ pub fn hashlib_insecure_hash_functions(
|
|||
if let Some(hash_func_name) = string_literal(name_arg) {
|
||||
if WEAK_HASHES.contains(&hash_func_name.to_lowercase().as_str()) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::HashlibInsecureHashFunction {
|
||||
HashlibInsecureHashFunction {
|
||||
string: hash_func_name.to_string(),
|
||||
},
|
||||
Range::from_located(name_arg),
|
||||
|
@ -73,7 +91,7 @@ pub fn hashlib_insecure_hash_functions(
|
|||
}
|
||||
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::HashlibInsecureHashFunction {
|
||||
HashlibInsecureHashFunction {
|
||||
string: (*func_name).to_string(),
|
||||
},
|
||||
Range::from_located(func),
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::Constant;
|
||||
|
||||
|
@ -5,7 +8,29 @@ use crate::ast::helpers::SimpleCallArgs;
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct Jinja2AutoescapeFalse {
|
||||
pub value: bool,
|
||||
}
|
||||
);
|
||||
impl Violation for Jinja2AutoescapeFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let Jinja2AutoescapeFalse { value } = self;
|
||||
match value {
|
||||
true => format!(
|
||||
"Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. \
|
||||
Ensure `autoescape=True` or use the `select_autoescape` function."
|
||||
),
|
||||
false => format!(
|
||||
"By default, jinja2 sets `autoescape` to `False`. Consider using \
|
||||
`autoescape=True` or the `select_autoescape` function to mitigate XSS \
|
||||
vulnerabilities."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// S701
|
||||
pub fn jinja2_autoescape_false(
|
||||
|
@ -29,20 +54,20 @@ pub fn jinja2_autoescape_false(
|
|||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id.as_str() != "select_autoescape" {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::Jinja2AutoescapeFalse { value: true },
|
||||
Jinja2AutoescapeFalse { value: true },
|
||||
Range::from_located(autoescape_arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => checker.diagnostics.push(Diagnostic::new(
|
||||
violations::Jinja2AutoescapeFalse { value: true },
|
||||
Jinja2AutoescapeFalse { value: true },
|
||||
Range::from_located(autoescape_arg),
|
||||
)),
|
||||
}
|
||||
} else {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::Jinja2AutoescapeFalse { value: false },
|
||||
Jinja2AutoescapeFalse { value: false },
|
||||
Range::from_located(func),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, Keyword};
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use crate::ast::helpers::SimpleCallArgs;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
|
|
|
@ -1,24 +1,30 @@
|
|||
pub use assert_used::assert_used;
|
||||
pub use bad_file_permissions::bad_file_permissions;
|
||||
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,
|
||||
pub use assert_used::{assert_used, AssertUsed};
|
||||
pub use bad_file_permissions::{bad_file_permissions, BadFilePermissions};
|
||||
pub use exec_used::{exec_used, ExecUsed};
|
||||
pub use hardcoded_bind_all_interfaces::{
|
||||
hardcoded_bind_all_interfaces, HardcodedBindAllInterfaces,
|
||||
};
|
||||
pub use hardcoded_tmp_directory::hardcoded_tmp_directory;
|
||||
pub use hashlib_insecure_hash_functions::hashlib_insecure_hash_functions;
|
||||
pub use jinja2_autoescape_false::jinja2_autoescape_false;
|
||||
pub use hardcoded_password_default::{hardcoded_password_default, HardcodedPasswordDefault};
|
||||
pub use hardcoded_password_func_arg::{hardcoded_password_func_arg, HardcodedPasswordFuncArg};
|
||||
pub use hardcoded_password_string::{
|
||||
assign_hardcoded_password_string, compare_to_hardcoded_password_string, HardcodedPasswordString,
|
||||
};
|
||||
pub use hardcoded_tmp_directory::{hardcoded_tmp_directory, HardcodedTempFile};
|
||||
pub use hashlib_insecure_hash_functions::{
|
||||
hashlib_insecure_hash_functions, HashlibInsecureHashFunction,
|
||||
};
|
||||
pub use jinja2_autoescape_false::{jinja2_autoescape_false, Jinja2AutoescapeFalse};
|
||||
pub use logging_config_insecure_listen::{
|
||||
logging_config_insecure_listen, LoggingConfigInsecureListen,
|
||||
};
|
||||
pub use request_with_no_cert_validation::request_with_no_cert_validation;
|
||||
pub use request_without_timeout::request_without_timeout;
|
||||
pub use snmp_insecure_version::snmp_insecure_version;
|
||||
pub use snmp_weak_cryptography::snmp_weak_cryptography;
|
||||
pub use request_with_no_cert_validation::{
|
||||
request_with_no_cert_validation, RequestWithNoCertValidation,
|
||||
};
|
||||
pub use request_without_timeout::{request_without_timeout, RequestWithoutTimeout};
|
||||
pub use snmp_insecure_version::{snmp_insecure_version, SnmpInsecureVersion};
|
||||
pub use snmp_weak_cryptography::{snmp_weak_cryptography, SnmpWeakCryptography};
|
||||
pub use try_except_pass::{try_except_pass, TryExceptPass};
|
||||
pub use unsafe_yaml_load::unsafe_yaml_load;
|
||||
pub use unsafe_yaml_load::{unsafe_yaml_load, UnsafeYAMLLoad};
|
||||
|
||||
mod assert_used;
|
||||
mod bad_file_permissions;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::Constant;
|
||||
|
||||
|
@ -5,7 +8,21 @@ use crate::ast::helpers::SimpleCallArgs;
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct RequestWithNoCertValidation {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for RequestWithNoCertValidation {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let RequestWithNoCertValidation { string } = self;
|
||||
format!(
|
||||
"Probable use of `{string}` call with `verify=False` disabling SSL certificate checks"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const REQUESTS_HTTP_VERBS: [&str; 7] = ["get", "options", "head", "post", "put", "patch", "delete"];
|
||||
const HTTPX_METHODS: [&str; 11] = [
|
||||
|
@ -48,7 +65,7 @@ pub fn request_with_no_cert_validation(
|
|||
} = &verify_arg.node
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::RequestWithNoCertValidation {
|
||||
RequestWithNoCertValidation {
|
||||
string: target.to_string(),
|
||||
},
|
||||
Range::from_located(verify_arg),
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::Constant;
|
||||
|
||||
|
@ -5,7 +8,24 @@ use crate::ast::helpers::SimpleCallArgs;
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct RequestWithoutTimeout {
|
||||
pub timeout: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for RequestWithoutTimeout {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let RequestWithoutTimeout { timeout } = self;
|
||||
match timeout {
|
||||
Some(value) => {
|
||||
format!("Probable use of requests call with timeout set to `{value}`")
|
||||
}
|
||||
None => format!("Probable use of requests call without timeout"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const HTTP_VERBS: [&str; 7] = ["get", "options", "head", "post", "put", "patch", "delete"];
|
||||
|
||||
|
@ -31,7 +51,7 @@ pub fn request_without_timeout(
|
|||
_ => None,
|
||||
} {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::RequestWithoutTimeout {
|
||||
RequestWithoutTimeout {
|
||||
timeout: Some(timeout),
|
||||
},
|
||||
Range::from_located(timeout_arg),
|
||||
|
@ -39,7 +59,7 @@ pub fn request_without_timeout(
|
|||
}
|
||||
} else {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::RequestWithoutTimeout { timeout: None },
|
||||
RequestWithoutTimeout { timeout: None },
|
||||
Range::from_located(func),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use num_traits::{One, Zero};
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::Constant;
|
||||
|
||||
|
@ -6,7 +9,16 @@ use crate::ast::helpers::SimpleCallArgs;
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct SnmpInsecureVersion;
|
||||
);
|
||||
impl Violation for SnmpInsecureVersion {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.")
|
||||
}
|
||||
}
|
||||
|
||||
/// S508
|
||||
pub fn snmp_insecure_version(
|
||||
|
@ -27,7 +39,7 @@ pub fn snmp_insecure_version(
|
|||
{
|
||||
if value.is_zero() || value.is_one() {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::SnmpInsecureVersion,
|
||||
SnmpInsecureVersion,
|
||||
Range::from_located(mp_model_arg),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,25 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, Keyword};
|
||||
|
||||
use crate::ast::helpers::SimpleCallArgs;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct SnmpWeakCryptography;
|
||||
);
|
||||
impl Violation for SnmpWeakCryptography {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!(
|
||||
"You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is \
|
||||
insecure."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// S509
|
||||
pub fn snmp_weak_cryptography(
|
||||
|
@ -19,7 +34,7 @@ pub fn snmp_weak_cryptography(
|
|||
let call_args = SimpleCallArgs::new(args, keywords);
|
||||
if call_args.len() < 3 {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::SnmpWeakCryptography,
|
||||
SnmpWeakCryptography,
|
||||
Range::from_located(func),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,37 @@
|
|||
use rustpython_ast::{Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use crate::ast::helpers::SimpleCallArgs;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::define_violation;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
use crate::violation::Violation;
|
||||
|
||||
define_violation!(
|
||||
pub struct UnsafeYAMLLoad {
|
||||
pub loader: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for UnsafeYAMLLoad {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UnsafeYAMLLoad { loader } = self;
|
||||
match loader {
|
||||
Some(name) => {
|
||||
format!(
|
||||
"Probable use of unsafe loader `{name}` with `yaml.load`. Allows \
|
||||
instantiation of arbitrary objects. Consider `yaml.safe_load`."
|
||||
)
|
||||
}
|
||||
None => format!(
|
||||
"Probable use of unsafe `yaml.load`. Allows instantiation of arbitrary objects. \
|
||||
Consider `yaml.safe_load`."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// S506
|
||||
pub fn unsafe_yaml_load(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
|
||||
|
@ -27,13 +54,13 @@ pub fn unsafe_yaml_load(checker: &mut Checker, func: &Expr, args: &[Expr], keywo
|
|||
_ => None,
|
||||
};
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::UnsafeYAMLLoad { loader },
|
||||
UnsafeYAMLLoad { loader },
|
||||
Range::from_located(loader_arg),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::UnsafeYAMLLoad { loader: None },
|
||||
UnsafeYAMLLoad { loader: None },
|
||||
Range::from_located(func),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1054,225 +1054,6 @@ impl Violation for ErrorSuffixOnExceptionName {
|
|||
}
|
||||
}
|
||||
|
||||
// flake8-bandit
|
||||
|
||||
define_violation!(
|
||||
pub struct Jinja2AutoescapeFalse {
|
||||
pub value: bool,
|
||||
}
|
||||
);
|
||||
impl Violation for Jinja2AutoescapeFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let Jinja2AutoescapeFalse { value } = self;
|
||||
match value {
|
||||
true => format!(
|
||||
"Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. \
|
||||
Ensure `autoescape=True` or use the `select_autoescape` function."
|
||||
),
|
||||
false => format!(
|
||||
"By default, jinja2 sets `autoescape` to `False`. Consider using \
|
||||
`autoescape=True` or the `select_autoescape` function to mitigate XSS \
|
||||
vulnerabilities."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AssertUsed;
|
||||
);
|
||||
impl Violation for AssertUsed {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use of `assert` detected")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ExecUsed;
|
||||
);
|
||||
impl Violation for ExecUsed {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use of `exec` detected")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct BadFilePermissions {
|
||||
pub mask: u16,
|
||||
}
|
||||
);
|
||||
impl Violation for BadFilePermissions {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let BadFilePermissions { mask } = self;
|
||||
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory",)
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedBindAllInterfaces;
|
||||
);
|
||||
impl Violation for HardcodedBindAllInterfaces {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Possible binding to all interfaces")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordString {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordString {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordString { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordFuncArg {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordFuncArg {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordFuncArg { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedPasswordDefault {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedPasswordDefault {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedPasswordDefault { string } = self;
|
||||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HardcodedTempFile {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HardcodedTempFile {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HardcodedTempFile { string } = self;
|
||||
format!(
|
||||
"Probable insecure usage of temporary file or directory: \"{}\"",
|
||||
string.escape_debug()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct RequestWithoutTimeout {
|
||||
pub timeout: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for RequestWithoutTimeout {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let RequestWithoutTimeout { timeout } = self;
|
||||
match timeout {
|
||||
Some(value) => {
|
||||
format!("Probable use of requests call with timeout set to `{value}`")
|
||||
}
|
||||
None => format!("Probable use of requests call without timeout"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct HashlibInsecureHashFunction {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for HashlibInsecureHashFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let HashlibInsecureHashFunction { string } = self;
|
||||
format!(
|
||||
"Probable use of insecure hash functions in `hashlib`: \"{}\"",
|
||||
string.escape_debug()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct RequestWithNoCertValidation {
|
||||
pub string: String,
|
||||
}
|
||||
);
|
||||
impl Violation for RequestWithNoCertValidation {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let RequestWithNoCertValidation { string } = self;
|
||||
format!(
|
||||
"Probable use of `{string}` call with `verify=False` disabling SSL certificate checks"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UnsafeYAMLLoad {
|
||||
pub loader: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for UnsafeYAMLLoad {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UnsafeYAMLLoad { loader } = self;
|
||||
match loader {
|
||||
Some(name) => {
|
||||
format!(
|
||||
"Probable use of unsafe loader `{name}` with `yaml.load`. Allows \
|
||||
instantiation of arbitrary objects. Consider `yaml.safe_load`."
|
||||
)
|
||||
}
|
||||
None => format!(
|
||||
"Probable use of unsafe `yaml.load`. Allows instantiation of arbitrary objects. \
|
||||
Consider `yaml.safe_load`."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SnmpInsecureVersion;
|
||||
);
|
||||
impl Violation for SnmpInsecureVersion {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SnmpWeakCryptography;
|
||||
);
|
||||
impl Violation for SnmpWeakCryptography {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!(
|
||||
"You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is \
|
||||
insecure."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-unused-arguments
|
||||
|
||||
define_violation!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue