mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Use matches!
for insecure hash rule (#5141)
This commit is contained in:
parent
13813dc1b1
commit
fab2a4adf7
2 changed files with 39 additions and 32 deletions
|
@ -1,8 +1,8 @@
|
|||
use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged};
|
||||
use rustpython_parser::ast::{Expr, Keyword, Ranged};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::SimpleCallArgs;
|
||||
use ruff_python_ast::helpers::{is_const_false, SimpleCallArgs};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
|
@ -21,26 +21,6 @@ impl Violation for HashlibInsecureHashFunction {
|
|||
}
|
||||
}
|
||||
|
||||
const WEAK_HASHES: [&str; 4] = ["md4", "md5", "sha", "sha1"];
|
||||
|
||||
fn is_used_for_security(call_args: &SimpleCallArgs) -> bool {
|
||||
match call_args.keyword_argument("usedforsecurity") {
|
||||
Some(expr) => !matches!(
|
||||
expr,
|
||||
Expr::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(false),
|
||||
..
|
||||
})
|
||||
),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
enum HashlibCall {
|
||||
New,
|
||||
WeakHash(&'static str),
|
||||
}
|
||||
|
||||
/// S324
|
||||
pub(crate) fn hashlib_insecure_hash_functions(
|
||||
checker: &mut Checker,
|
||||
|
@ -51,15 +31,13 @@ pub(crate) fn hashlib_insecure_hash_functions(
|
|||
if let Some(hashlib_call) = checker
|
||||
.semantic()
|
||||
.resolve_call_path(func)
|
||||
.and_then(|call_path| {
|
||||
if matches!(call_path.as_slice(), ["hashlib", "new"]) {
|
||||
Some(HashlibCall::New)
|
||||
} else {
|
||||
WEAK_HASHES
|
||||
.iter()
|
||||
.find(|hash| call_path.as_slice() == ["hashlib", hash])
|
||||
.map(|hash| HashlibCall::WeakHash(hash))
|
||||
}
|
||||
.and_then(|call_path| match call_path.as_slice() {
|
||||
["hashlib", "new"] => Some(HashlibCall::New),
|
||||
["hashlib", "md4"] => Some(HashlibCall::WeakHash("md4")),
|
||||
["hashlib", "md5"] => Some(HashlibCall::WeakHash("md5")),
|
||||
["hashlib", "sha"] => Some(HashlibCall::WeakHash("sha")),
|
||||
["hashlib", "sha1"] => Some(HashlibCall::WeakHash("sha1")),
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
match hashlib_call {
|
||||
|
@ -72,7 +50,12 @@ pub(crate) fn hashlib_insecure_hash_functions(
|
|||
|
||||
if let Some(name_arg) = call_args.argument("name", 0) {
|
||||
if let Some(hash_func_name) = string_literal(name_arg) {
|
||||
if WEAK_HASHES.contains(&hash_func_name.to_lowercase().as_str()) {
|
||||
// `hashlib.new` accepts both lowercase and uppercase names for hash
|
||||
// functions.
|
||||
if matches!(
|
||||
hash_func_name,
|
||||
"md4" | "md5" | "sha" | "sha1" | "MD4" | "MD5" | "SHA" | "SHA1"
|
||||
) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
HashlibInsecureHashFunction {
|
||||
string: hash_func_name.to_string(),
|
||||
|
@ -100,3 +83,15 @@ pub(crate) fn hashlib_insecure_hash_functions(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_used_for_security(call_args: &SimpleCallArgs) -> bool {
|
||||
match call_args.keyword_argument("usedforsecurity") {
|
||||
Some(expr) => !is_const_false(expr),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
enum HashlibCall {
|
||||
New,
|
||||
WeakHash(&'static str),
|
||||
}
|
||||
|
|
|
@ -634,6 +634,18 @@ pub const fn is_const_true(expr: &Expr) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
/// Return `true` if an [`Expr`] is `False`.
|
||||
pub const fn is_const_false(expr: &Expr) -> bool {
|
||||
matches!(
|
||||
expr,
|
||||
Expr::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(false),
|
||||
kind: None,
|
||||
..
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return `true` if a keyword argument is present with a non-`None` value.
|
||||
pub fn has_non_none_keyword(keywords: &[Keyword], keyword: &str) -> bool {
|
||||
find_keyword(keywords, keyword).map_or(false, |keyword| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue