Move flake8-bandit violations (#2525)

This commit is contained in:
Aarni Koskela 2023-02-03 14:39:49 +02:00 committed by GitHub
parent c96ba6dec4
commit 81b60cf9fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 324 additions and 293 deletions

View file

@ -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,

View file

@ -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())),
)
}

View file

@ -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),
));
}

View file

@ -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)))
}

View file

@ -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
}

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),
));
}

View file

@ -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;

View file

@ -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;

View file

@ -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),

View file

@ -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),
));
}

View file

@ -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),
));
}

View file

@ -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),
));
}

View file

@ -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),
));
}

View file

@ -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!(