From 7705ba2798e9c565f3dc5104829491cf0e4d5a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Rami=CC=81rez=20Mondrago=CC=81n?= Date: Wed, 4 Jan 2023 15:12:29 -0600 Subject: [PATCH 1/7] Implement flake8-bandit rule `S108` --- README.md | 39 +++++++++ flake8_to_ruff/src/converter.rs | 7 ++ resources/test/fixtures/flake8_bandit/S108.py | 16 ++++ ruff.schema.json | 38 +++++++++ src/checkers/ast.rs | 9 ++ src/flake8_bandit/checks/hardcoded_tmp_dir.rs | 20 +++++ src/flake8_bandit/checks/mod.rs | 2 + src/flake8_bandit/mod.rs | 51 +++++++++--- src/flake8_bandit/settings.rs | 83 +++++++++++++++++++ ... => ruff__flake8_bandit__tests__S101.snap} | 0 ... => ruff__flake8_bandit__tests__S102.snap} | 0 ... => ruff__flake8_bandit__tests__S103.snap} | 0 ... => ruff__flake8_bandit__tests__S104.snap} | 0 ... => ruff__flake8_bandit__tests__S105.snap} | 0 ... => ruff__flake8_bandit__tests__S106.snap} | 0 ... => ruff__flake8_bandit__tests__S107.snap} | 0 ...f__flake8_bandit__tests__S108_default.snap | 35 ++++++++ ...ff__flake8_bandit__tests__S108_extend.snap | 45 ++++++++++ ...__flake8_bandit__tests__S108_override.snap | 15 ++++ src/registry.rs | 11 +++ src/registry_gen.rs | 7 ++ src/settings/configuration.rs | 5 +- src/settings/mod.rs | 10 ++- src/settings/options.rs | 5 +- src/settings/pyproject.rs | 8 +- 25 files changed, 391 insertions(+), 15 deletions(-) create mode 100644 resources/test/fixtures/flake8_bandit/S108.py create mode 100644 src/flake8_bandit/checks/hardcoded_tmp_dir.rs create mode 100644 src/flake8_bandit/settings.rs rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S101_S101.py.snap => ruff__flake8_bandit__tests__S101.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S102_S102.py.snap => ruff__flake8_bandit__tests__S102.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S103_S103.py.snap => ruff__flake8_bandit__tests__S103.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S104_S104.py.snap => ruff__flake8_bandit__tests__S104.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S105_S105.py.snap => ruff__flake8_bandit__tests__S105.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S106_S106.py.snap => ruff__flake8_bandit__tests__S106.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S107_S107.py.snap => ruff__flake8_bandit__tests__S107.snap} (100%) create mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap create mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_extend.snap create mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap diff --git a/README.md b/README.md index afee94227f688..f0e53dc2f420a 100644 --- a/README.md +++ b/README.md @@ -770,6 +770,7 @@ For more, see [flake8-bandit](https://pypi.org/project/flake8-bandit/4.1.1/) on | S105 | HardcodedPasswordString | Possible hardcoded password: `"..."` | | | S106 | HardcodedPasswordFuncArg | Possible hardcoded password: `"..."` | | | S107 | HardcodedPasswordDefault | Possible hardcoded password: `"..."` | | +| S108 | HardcodedTempFile | Probable insecure usage of temp file/directory: `"..."` | | ### flake8-blind-except (BLE) @@ -2361,6 +2362,44 @@ suppress-none-returning = true --- +### `flake8-bandit` + +#### [`hardcoded-tmp-directory`](#hardcoded-tmp-directory) + +List of directories that are considered temporary. + +**Default value**: `["/tmp", "/var/tmp", "/dev/shm"]` + +**Type**: `Vec` + +**Example usage**: + +```toml +[tool.ruff.flake8-bandit] +hardcoded_tmp_directory = ["/foo/bar"] +``` + +--- + +#### [`hardcoded-tmp-directory-extend`](#hardcoded-tmp-directory-extend) + +List of directories that are considered temporary. +These directories are added to the list in +`hardcoded_tmp_directory`. + +**Default value**: `[]` + +**Type**: `Vec` + +**Example usage**: + +```toml +[tool.ruff.flake8-bandit] +extend_hardcoded_tmp_directory = ["/foo/bar"] +``` + +--- + ### `flake8-bugbear` #### [`extend-immutable-calls`](#extend-immutable-calls) diff --git a/flake8_to_ruff/src/converter.rs b/flake8_to_ruff/src/converter.rs index 79b629091e790..a8c3913d1224c 100644 --- a/flake8_to_ruff/src/converter.rs +++ b/flake8_to_ruff/src/converter.rs @@ -393,6 +393,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -455,6 +456,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -517,6 +519,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -579,6 +582,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -641,6 +645,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -712,6 +717,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -777,6 +783,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, diff --git a/resources/test/fixtures/flake8_bandit/S108.py b/resources/test/fixtures/flake8_bandit/S108.py new file mode 100644 index 0000000000000..d60b808cb584a --- /dev/null +++ b/resources/test/fixtures/flake8_bandit/S108.py @@ -0,0 +1,16 @@ +# ok +with open("/abc/tmp", "w") as f: + f.write("def") + +with open("/tmp/abc", "w") as f: + f.write("def") + +with open("/var/tmp/123", "w") as f: + f.write("def") + +with open("/dev/shm/unit/test", "w") as f: + f.write("def") + +# not ok by config +with open("/foo/bar", "w") as f: + f.write("def") diff --git a/ruff.schema.json b/ruff.schema.json index 8f82f95db52f9..28e6624dd1c42 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -121,6 +121,17 @@ } ] }, + "flake8-bandit": { + "description": "Options for the `flake8-bandit` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8BanditOptions" + }, + { + "type": "null" + } + ] + }, "flake8-bugbear": { "description": "Options for the `flake8-bugbear` plugin.", "anyOf": [ @@ -915,6 +926,7 @@ "S105", "S106", "S107", + "S108", "SIM", "SIM1", "SIM10", @@ -1082,6 +1094,32 @@ }, "additionalProperties": false }, + "Flake8BanditOptions": { + "type": "object", + "properties": { + "hardcoded-tmp-directory": { + "description": "List of directories that are considered temporary.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "hardcoded-tmp-directory-extend": { + "description": "List of directories that are considered temporary. These directories are added to the list in `hardcoded_tmp_directory`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, "Flake8BugbearOptions": { "type": "object", "properties": { diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index 71f7a1d033ca5..bfc93e70d8f1f 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -2533,6 +2533,15 @@ where self.add_check(check); } } + if self.settings.enabled.contains(&CheckCode::S108) { + if let Some(check) = flake8_bandit::checks::hardcoded_tmp_dir( + expr, + value, + &mut self.settings.flake8_bandit.all_hardcoded_tmp_directories(), + ) { + self.add_check(check); + } + } if self.settings.enabled.contains(&CheckCode::UP025) { pyupgrade::plugins::rewrite_unicode_literal(self, expr, kind); } diff --git a/src/flake8_bandit/checks/hardcoded_tmp_dir.rs b/src/flake8_bandit/checks/hardcoded_tmp_dir.rs new file mode 100644 index 0000000000000..ba4ddb16d44a0 --- /dev/null +++ b/src/flake8_bandit/checks/hardcoded_tmp_dir.rs @@ -0,0 +1,20 @@ +use rustpython_ast::Expr; + +use crate::ast::types::Range; +use crate::registry::{Check, CheckKind}; + +/// S108 +pub fn hardcoded_tmp_dir<'a>( + expr: &Expr, + value: &str, + prefixes: &mut impl Iterator, +) -> Option { + if prefixes.any(|prefix| value.starts_with(prefix)) { + Some(Check::new( + CheckKind::HardcodedTempFile(value.to_string()), + Range::from_located(expr), + )) + } else { + None + } +} diff --git a/src/flake8_bandit/checks/mod.rs b/src/flake8_bandit/checks/mod.rs index d5189a5c2a82f..a7777c7a3fbdb 100644 --- a/src/flake8_bandit/checks/mod.rs +++ b/src/flake8_bandit/checks/mod.rs @@ -7,6 +7,7 @@ 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 hardcoded_tmp_dir::hardcoded_tmp_dir; mod assert_used; mod bad_file_permissions; @@ -15,3 +16,4 @@ mod hardcoded_bind_all_interfaces; mod hardcoded_password_default; mod hardcoded_password_func_arg; mod hardcoded_password_string; +mod hardcoded_tmp_dir; diff --git a/src/flake8_bandit/mod.rs b/src/flake8_bandit/mod.rs index f65b108c0e1f1..fa35d13aadc20 100644 --- a/src/flake8_bandit/mod.rs +++ b/src/flake8_bandit/mod.rs @@ -1,5 +1,6 @@ pub mod checks; mod helpers; +pub mod settings; #[cfg(test)] mod tests { @@ -8,26 +9,54 @@ mod tests { use anyhow::Result; use test_case::test_case; + use crate::flake8_bandit::settings::Settings; use crate::linter::test_path; use crate::registry::CheckCode; use crate::settings; - #[test_case(CheckCode::S101, Path::new("S101.py"); "S101")] - #[test_case(CheckCode::S102, Path::new("S102.py"); "S102")] - #[test_case(CheckCode::S103, Path::new("S103.py"); "S103")] - #[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")] - fn checks(check_code: CheckCode, path: &Path) -> Result<()> { - let snapshot = format!("{}_{}", check_code.as_ref(), path.to_string_lossy()); + #[test_case(CheckCode::S101, Path::new("S101.py"), Settings::default(), "S101"; "S101")] + #[test_case(CheckCode::S102, Path::new("S102.py"), Settings::default(), "S102"; "S102")] + #[test_case(CheckCode::S103, Path::new("S103.py"), Settings::default(), "S103"; "S103")] + #[test_case(CheckCode::S104, Path::new("S104.py"), Settings::default(), "S104"; "S104")] + #[test_case(CheckCode::S105, Path::new("S105.py"), Settings::default(), "S105"; "S105")] + #[test_case(CheckCode::S106, Path::new("S106.py"), Settings::default(), "S106"; "S106")] + #[test_case(CheckCode::S107, Path::new("S107.py"), Settings::default(), "S107"; "S107")] + #[test_case(CheckCode::S108, Path::new("S108.py"), Settings::default(), "S108_default"; "S108_0")] + #[test_case( + CheckCode::S108, Path::new("S108.py"), + Settings { + hardcoded_tmp_directory: vec!["/foo".to_string()], + ..Settings::default() + }, + "S108_override"; + "S108_1" + )] + #[test_case( + CheckCode::S108, + Path::new("S108.py"), + Settings { + hardcoded_tmp_directory_extend: vec!["/foo".to_string()], + ..Settings::default() + }, + "S108_extend"; + "S108_2" + )] + fn checks( + check_code: CheckCode, + path: &Path, + plugin_settings: Settings, + label: &str, + ) -> Result<()> { let checks = test_path( Path::new("./resources/test/fixtures/flake8_bandit") .join(path) .as_path(), - &settings::Settings::for_rule(check_code), + &settings::Settings { + flake8_bandit: plugin_settings, + ..settings::Settings::for_rule(check_code) + }, )?; - insta::assert_yaml_snapshot!(snapshot, checks); + insta::assert_yaml_snapshot!(label, checks); Ok(()) } } diff --git a/src/flake8_bandit/settings.rs b/src/flake8_bandit/settings.rs new file mode 100644 index 0000000000000..505ce5c33d1c9 --- /dev/null +++ b/src/flake8_bandit/settings.rs @@ -0,0 +1,83 @@ +//! Settings for the `flake8-bandit` plugin. + +use ruff_macros::ConfigurationOptions; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +fn default_tmp_dirs() -> Vec { + ["/tmp", "/var/tmp", "/dev/shm"] + .map(std::string::ToString::to_string) + .to_vec() +} + +#[derive( + Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema, +)] +#[serde( + deny_unknown_fields, + rename_all = "kebab-case", + rename = "Flake8BanditOptions" +)] +pub struct Options { + #[option( + default = "[\"/tmp\", \"/var/tmp\", \"/dev/shm\"]", + value_type = "Vec", + example = "hardcoded_tmp_directory = [\"/foo/bar\"]" + )] + /// List of directories that are considered temporary. + pub hardcoded_tmp_directory: Option>, + #[option( + default = "[]", + value_type = "Vec", + example = "extend_hardcoded_tmp_directory = [\"/foo/bar\"]" + )] + /// List of directories that are considered temporary. + /// These directories are added to the list in + /// `hardcoded_tmp_directory`. + pub hardcoded_tmp_directory_extend: Option>, +} + +#[derive(Debug, Hash)] +pub struct Settings { + pub hardcoded_tmp_directory: Vec, + pub hardcoded_tmp_directory_extend: Vec, +} + +impl From for Settings { + fn from(options: Options) -> Self { + Self { + hardcoded_tmp_directory: options + .hardcoded_tmp_directory + .unwrap_or_else(default_tmp_dirs), + hardcoded_tmp_directory_extend: options + .hardcoded_tmp_directory_extend + .unwrap_or_default(), + } + } +} +impl From for Options { + fn from(settings: Settings) -> Self { + Self { + hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory), + hardcoded_tmp_directory_extend: Some(settings.hardcoded_tmp_directory_extend), + } + } +} + +impl Default for Settings { + fn default() -> Self { + Self { + hardcoded_tmp_directory: default_tmp_dirs(), + hardcoded_tmp_directory_extend: Vec::new(), + } + } +} + +impl Settings { + /// Returns an iterator over all directories that are considered temporary. + pub fn all_hardcoded_tmp_directories(&'_ self) -> impl Iterator { + self.hardcoded_tmp_directory + .iter() + .chain(self.hardcoded_tmp_directory_extend.iter()) + } +} diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101_S101.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101_S101.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102_S102.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102_S102.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103_S103.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103_S103.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104_S104.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104_S104.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105_S105.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105_S105.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106_S106.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106_S106.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107_S107.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107_S107.py.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap new file mode 100644 index 0000000000000..cfd8f1c96e86a --- /dev/null +++ b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap @@ -0,0 +1,35 @@ +--- +source: src/flake8_bandit/mod.rs +expression: checks +--- +- kind: + HardcodedTempFile: /tmp/abc + location: + row: 5 + column: 10 + end_location: + row: 5 + column: 20 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /var/tmp/123 + location: + row: 8 + column: 10 + end_location: + row: 8 + column: 24 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /dev/shm/unit/test + location: + row: 11 + column: 10 + end_location: + row: 11 + column: 30 + fix: ~ + parent: ~ + diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_extend.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_extend.snap new file mode 100644 index 0000000000000..5d8bd2338b152 --- /dev/null +++ b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_extend.snap @@ -0,0 +1,45 @@ +--- +source: src/flake8_bandit/mod.rs +expression: checks +--- +- kind: + HardcodedTempFile: /tmp/abc + location: + row: 5 + column: 10 + end_location: + row: 5 + column: 20 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /var/tmp/123 + location: + row: 8 + column: 10 + end_location: + row: 8 + column: 24 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /dev/shm/unit/test + location: + row: 11 + column: 10 + end_location: + row: 11 + column: 30 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /foo/bar + location: + row: 15 + column: 10 + end_location: + row: 15 + column: 20 + fix: ~ + parent: ~ + diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap new file mode 100644 index 0000000000000..8f29b55446ca4 --- /dev/null +++ b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap @@ -0,0 +1,15 @@ +--- +source: src/flake8_bandit/mod.rs +expression: checks +--- +- kind: + HardcodedTempFile: /foo/bar + location: + row: 15 + column: 10 + end_location: + row: 15 + column: 20 + fix: ~ + parent: ~ + diff --git a/src/registry.rs b/src/registry.rs index b4cb79540cbe9..43761f78c46a1 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -327,6 +327,7 @@ pub enum CheckCode { S105, S106, S107, + S108, // flake8-boolean-trap FBT001, FBT002, @@ -1060,6 +1061,7 @@ pub enum CheckKind { HardcodedPasswordString(String), HardcodedPasswordFuncArg(String), HardcodedPasswordDefault(String), + HardcodedTempFile(String), // mccabe FunctionIsTooComplex(String, usize), // flake8-boolean-trap @@ -1512,6 +1514,7 @@ impl CheckCode { CheckCode::S105 => CheckKind::HardcodedPasswordString("...".to_string()), CheckCode::S106 => CheckKind::HardcodedPasswordFuncArg("...".to_string()), CheckCode::S107 => CheckKind::HardcodedPasswordDefault("...".to_string()), + CheckCode::S108 => CheckKind::HardcodedTempFile("...".to_string()), // mccabe CheckCode::C901 => CheckKind::FunctionIsTooComplex("...".to_string(), 10), // flake8-boolean-trap @@ -1913,6 +1916,7 @@ impl CheckCode { CheckCode::S105 => CheckCategory::Flake8Bandit, CheckCode::S106 => CheckCategory::Flake8Bandit, CheckCode::S107 => CheckCategory::Flake8Bandit, + CheckCode::S108 => CheckCategory::Flake8Bandit, // flake8-simplify CheckCode::SIM105 => CheckCategory::Flake8Simplify, CheckCode::SIM118 => CheckCategory::Flake8Simplify, @@ -2277,6 +2281,7 @@ impl CheckKind { CheckKind::HardcodedPasswordString(..) => &CheckCode::S105, CheckKind::HardcodedPasswordFuncArg(..) => &CheckCode::S106, CheckKind::HardcodedPasswordDefault(..) => &CheckCode::S107, + CheckKind::HardcodedTempFile(..) => &CheckCode::S108, // mccabe CheckKind::FunctionIsTooComplex(..) => &CheckCode::C901, // flake8-boolean-trap @@ -3210,6 +3215,12 @@ impl CheckKind { string.escape_debug() ) } + CheckKind::HardcodedTempFile(string) => { + format!( + "Probable insecure usage of temp file/directory: `\"{}\"`", + string.escape_debug() + ) + } // flake8-blind-except CheckKind::BlindExcept(name) => format!("Do not catch blind exception: `{name}`"), // mccabe diff --git a/src/registry_gen.rs b/src/registry_gen.rs index 34f113ce9ee1d..d390b91be3eea 100644 --- a/src/registry_gen.rs +++ b/src/registry_gen.rs @@ -514,6 +514,7 @@ pub enum CheckCodePrefix { S105, S106, S107, + S108, SIM, SIM1, SIM10, @@ -909,6 +910,7 @@ impl CheckCodePrefix { CheckCode::S105, CheckCode::S106, CheckCode::S107, + CheckCode::S108, CheckCode::FBT001, CheckCode::FBT002, CheckCode::FBT003, @@ -2596,6 +2598,7 @@ impl CheckCodePrefix { CheckCode::S105, CheckCode::S106, CheckCode::S107, + CheckCode::S108, ], CheckCodePrefix::S1 => vec![ CheckCode::S101, @@ -2605,6 +2608,7 @@ impl CheckCodePrefix { CheckCode::S105, CheckCode::S106, CheckCode::S107, + CheckCode::S108, ], CheckCodePrefix::S10 => vec![ CheckCode::S101, @@ -2614,6 +2618,7 @@ impl CheckCodePrefix { CheckCode::S105, CheckCode::S106, CheckCode::S107, + CheckCode::S108, ], CheckCodePrefix::S101 => vec![CheckCode::S101], CheckCodePrefix::S102 => vec![CheckCode::S102], @@ -2622,6 +2627,7 @@ impl CheckCodePrefix { CheckCodePrefix::S105 => vec![CheckCode::S105], CheckCodePrefix::S106 => vec![CheckCode::S106], CheckCodePrefix::S107 => vec![CheckCode::S107], + CheckCodePrefix::S108 => vec![CheckCode::S108], CheckCodePrefix::SIM => vec![ CheckCode::SIM105, CheckCode::SIM118, @@ -3602,6 +3608,7 @@ impl CheckCodePrefix { CheckCodePrefix::S105 => SuffixLength::Three, CheckCodePrefix::S106 => SuffixLength::Three, CheckCodePrefix::S107 => SuffixLength::Three, + CheckCodePrefix::S108 => SuffixLength::Three, CheckCodePrefix::SIM => SuffixLength::Zero, CheckCodePrefix::SIM1 => SuffixLength::One, CheckCodePrefix::SIM10 => SuffixLength::Two, diff --git a/src/settings/configuration.rs b/src/settings/configuration.rs index 77c48bf9c9c19..e6464b3a79796 100644 --- a/src/settings/configuration.rs +++ b/src/settings/configuration.rs @@ -20,7 +20,7 @@ use crate::settings::types::{ FilePattern, PerFileIgnore, PythonVersion, SerializationFormat, Version, }; use crate::{ - flake8_annotations, flake8_bugbear, flake8_errmsg, flake8_import_conventions, + flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, fs, isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pyupgrade, }; @@ -56,6 +56,7 @@ pub struct Configuration { pub update_check: Option, // Plugins pub flake8_annotations: Option, + pub flake8_bandit: Option, pub flake8_bugbear: Option, pub flake8_errmsg: Option, pub flake8_import_conventions: Option, @@ -155,6 +156,7 @@ impl Configuration { update_check: options.update_check, // Plugins flake8_annotations: options.flake8_annotations, + flake8_bandit: options.flake8_bandit, flake8_bugbear: options.flake8_bugbear, flake8_errmsg: options.flake8_errmsg, flake8_import_conventions: options.flake8_import_conventions, @@ -217,6 +219,7 @@ impl Configuration { update_check: self.update_check.or(config.update_check), // Plugins flake8_annotations: self.flake8_annotations.or(config.flake8_annotations), + flake8_bandit: self.flake8_bandit.or(config.flake8_bandit), flake8_bugbear: self.flake8_bugbear.or(config.flake8_bugbear), flake8_errmsg: self.flake8_errmsg.or(config.flake8_errmsg), flake8_import_conventions: self diff --git a/src/settings/mod.rs b/src/settings/mod.rs index a5b38829561e5..f44e0f4c66405 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -24,7 +24,7 @@ use crate::settings::types::{ FilePattern, PerFileIgnore, PythonVersion, SerializationFormat, Version, }; use crate::{ - flake8_annotations, flake8_bugbear, flake8_errmsg, flake8_import_conventions, + flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort, mccabe, one_time_warning, pep8_naming, pycodestyle, pydocstyle, pyupgrade, }; @@ -64,6 +64,7 @@ pub struct Settings { pub update_check: bool, // Plugins pub flake8_annotations: flake8_annotations::settings::Settings, + pub flake8_bandit: flake8_bandit::settings::Settings, pub flake8_bugbear: flake8_bugbear::settings::Settings, pub flake8_errmsg: flake8_errmsg::settings::Settings, pub flake8_import_conventions: flake8_import_conventions::settings::Settings, @@ -184,6 +185,10 @@ impl Settings { .flake8_annotations .map(std::convert::Into::into) .unwrap_or_default(), + flake8_bandit: config + .flake8_bandit + .map(std::convert::Into::into) + .unwrap_or_default(), flake8_bugbear: config .flake8_bugbear .map(std::convert::Into::into) @@ -264,6 +269,7 @@ impl Settings { task_tags: vec!["TODO".to_string(), "FIXME".to_string()], update_check: false, flake8_annotations: flake8_annotations::settings::Settings::default(), + flake8_bandit: flake8_bandit::settings::Settings::default(), flake8_bugbear: flake8_bugbear::settings::Settings::default(), flake8_errmsg: flake8_errmsg::settings::Settings::default(), flake8_import_conventions: flake8_import_conventions::settings::Settings::default(), @@ -305,6 +311,7 @@ impl Settings { task_tags: vec!["TODO".to_string()], update_check: false, flake8_annotations: flake8_annotations::settings::Settings::default(), + flake8_bandit: flake8_bandit::settings::Settings::default(), flake8_bugbear: flake8_bugbear::settings::Settings::default(), flake8_errmsg: flake8_errmsg::settings::Settings::default(), flake8_import_conventions: flake8_import_conventions::settings::Settings::default(), @@ -365,6 +372,7 @@ impl Hash for Settings { self.target_version.hash(state); // Add plugin properties in alphabetical order. self.flake8_annotations.hash(state); + self.flake8_bandit.hash(state); self.flake8_bugbear.hash(state); self.flake8_errmsg.hash(state); self.flake8_import_conventions.hash(state); diff --git a/src/settings/options.rs b/src/settings/options.rs index 094cfe9dcc79a..2a64ce1564a14 100644 --- a/src/settings/options.rs +++ b/src/settings/options.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::registry_gen::CheckCodePrefix; use crate::settings::types::{PythonVersion, SerializationFormat, Version}; use crate::{ - flake8_annotations, flake8_bugbear, flake8_errmsg, flake8_import_conventions, + flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pyupgrade, }; @@ -362,6 +362,9 @@ pub struct Options { /// Options for the `flake8-annotations` plugin. pub flake8_annotations: Option, #[option_group] + /// Options for the `flake8-bandit` plugin. + pub flake8_bandit: Option, + #[option_group] /// Options for the `flake8-bugbear` plugin. pub flake8_bugbear: Option, #[option_group] diff --git a/src/settings/pyproject.rs b/src/settings/pyproject.rs index cb21804745b9a..d6c0b70a4693c 100644 --- a/src/settings/pyproject.rs +++ b/src/settings/pyproject.rs @@ -191,6 +191,7 @@ mod tests { task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -247,6 +248,7 @@ line-length = 79 update_check: None, cache_dir: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -303,8 +305,9 @@ exclude = ["foo.py"] task_tags: None, update_check: None, flake8_annotations: None, - flake8_errmsg: None, + flake8_bandit: None, flake8_bugbear: None, + flake8_errmsg: None, flake8_pytest_style: None, flake8_quotes: None, flake8_tidy_imports: None, @@ -359,6 +362,7 @@ select = ["E501"] task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -416,6 +420,7 @@ ignore = ["E501"] task_tags: None, update_check: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: None, flake8_errmsg: None, flake8_pytest_style: None, @@ -514,6 +519,7 @@ other-attribute = 1 target_version: None, show_source: None, flake8_annotations: None, + flake8_bandit: None, flake8_bugbear: Some(flake8_bugbear::settings::Options { extend_immutable_calls: Some(vec![ "fastapi.Depends".to_string(), From 86b702b10f9e4a1d6560b98d27c671382c57a9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Rami=CC=81rez=20Mondrago=CC=81n?= Date: Wed, 4 Jan 2023 18:50:06 -0600 Subject: [PATCH 2/7] Update lib_wasm.rs --- src/lib_wasm.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib_wasm.rs b/src/lib_wasm.rs index 806c39e4b9b87..bf9257f926714 100644 --- a/src/lib_wasm.rs +++ b/src/lib_wasm.rs @@ -16,9 +16,9 @@ use crate::settings::{flags, Settings}; use crate::source_code_locator::SourceCodeLocator; use crate::source_code_style::SourceCodeStyleDetector; use crate::{ - directives, flake8_annotations, flake8_bugbear, flake8_errmsg, flake8_import_conventions, - flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort, - mccabe, pep8_naming, pycodestyle, pydocstyle, pyupgrade, + directives, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, + flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_tidy_imports, + flake8_unused_arguments, isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pyupgrade, }; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -116,6 +116,7 @@ pub fn defaultSettings() -> Result { update_check: None, // Use default options for all plugins. flake8_annotations: Some(flake8_annotations::settings::Settings::default().into()), + flake8_bandit: Some(flake8_bandit::settings::Settings::default().into()), flake8_bugbear: Some(flake8_bugbear::settings::Settings::default().into()), flake8_errmsg: Some(flake8_errmsg::settings::Settings::default().into()), flake8_pytest_style: Some(flake8_pytest_style::settings::Settings::default().into()), From 0607199ccdcdb639a7bc4c1a9460086eb5dbaa2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Rami=CC=81rez=20Mondrago=CC=81n?= Date: Wed, 4 Jan 2023 20:01:00 -0600 Subject: [PATCH 3/7] Use a single `hardcoded_tmp_directory` in bandit internal settings --- src/checkers/ast.rs | 2 +- src/flake8_bandit/checks/hardcoded_tmp_dir.rs | 8 +-- src/flake8_bandit/mod.rs | 71 +++++++++---------- src/flake8_bandit/settings.rs | 30 ++------ ...__flake8_bandit__tests__S101_S101.py.snap} | 0 ...__flake8_bandit__tests__S102_S102.py.snap} | 0 ...__flake8_bandit__tests__S103_S103.py.snap} | 0 ...__flake8_bandit__tests__S104_S104.py.snap} | 0 ...__flake8_bandit__tests__S105_S105.py.snap} | 0 ...__flake8_bandit__tests__S106_S106.py.snap} | 0 ...__flake8_bandit__tests__S107_S107.py.snap} | 0 ...f__flake8_bandit__tests__S108_S108.py.snap | 35 +++++++++ 12 files changed, 75 insertions(+), 71 deletions(-) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S101.snap => ruff__flake8_bandit__tests__S101_S101.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S102.snap => ruff__flake8_bandit__tests__S102_S102.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S103.snap => ruff__flake8_bandit__tests__S103_S103.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S104.snap => ruff__flake8_bandit__tests__S104_S104.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S105.snap => ruff__flake8_bandit__tests__S105_S105.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S106.snap => ruff__flake8_bandit__tests__S106_S106.py.snap} (100%) rename src/flake8_bandit/snapshots/{ruff__flake8_bandit__tests__S107.snap => ruff__flake8_bandit__tests__S107_S107.py.snap} (100%) create mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_S108.py.snap diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index bfc93e70d8f1f..4797b0665aeec 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -2537,7 +2537,7 @@ where if let Some(check) = flake8_bandit::checks::hardcoded_tmp_dir( expr, value, - &mut self.settings.flake8_bandit.all_hardcoded_tmp_directories(), + &self.settings.flake8_bandit.hardcoded_tmp_directory, ) { self.add_check(check); } diff --git a/src/flake8_bandit/checks/hardcoded_tmp_dir.rs b/src/flake8_bandit/checks/hardcoded_tmp_dir.rs index ba4ddb16d44a0..66a9ea9a91611 100644 --- a/src/flake8_bandit/checks/hardcoded_tmp_dir.rs +++ b/src/flake8_bandit/checks/hardcoded_tmp_dir.rs @@ -4,12 +4,8 @@ use crate::ast::types::Range; use crate::registry::{Check, CheckKind}; /// S108 -pub fn hardcoded_tmp_dir<'a>( - expr: &Expr, - value: &str, - prefixes: &mut impl Iterator, -) -> Option { - if prefixes.any(|prefix| value.starts_with(prefix)) { +pub fn hardcoded_tmp_dir(expr: &Expr, value: &str, prefixes: &[String]) -> Option { + if prefixes.iter().any(|prefix| value.starts_with(prefix)) { Some(Check::new( CheckKind::HardcodedTempFile(value.to_string()), Range::from_located(expr), diff --git a/src/flake8_bandit/mod.rs b/src/flake8_bandit/mod.rs index fa35d13aadc20..f7dc93c6ae209 100644 --- a/src/flake8_bandit/mod.rs +++ b/src/flake8_bandit/mod.rs @@ -9,54 +9,47 @@ mod tests { use anyhow::Result; use test_case::test_case; - use crate::flake8_bandit::settings::Settings; use crate::linter::test_path; use crate::registry::CheckCode; - use crate::settings; + use crate::{flake8_bandit, Settings}; - #[test_case(CheckCode::S101, Path::new("S101.py"), Settings::default(), "S101"; "S101")] - #[test_case(CheckCode::S102, Path::new("S102.py"), Settings::default(), "S102"; "S102")] - #[test_case(CheckCode::S103, Path::new("S103.py"), Settings::default(), "S103"; "S103")] - #[test_case(CheckCode::S104, Path::new("S104.py"), Settings::default(), "S104"; "S104")] - #[test_case(CheckCode::S105, Path::new("S105.py"), Settings::default(), "S105"; "S105")] - #[test_case(CheckCode::S106, Path::new("S106.py"), Settings::default(), "S106"; "S106")] - #[test_case(CheckCode::S107, Path::new("S107.py"), Settings::default(), "S107"; "S107")] - #[test_case(CheckCode::S108, Path::new("S108.py"), Settings::default(), "S108_default"; "S108_0")] - #[test_case( - CheckCode::S108, Path::new("S108.py"), - Settings { - hardcoded_tmp_directory: vec!["/foo".to_string()], - ..Settings::default() - }, - "S108_override"; - "S108_1" - )] - #[test_case( - CheckCode::S108, - Path::new("S108.py"), - Settings { - hardcoded_tmp_directory_extend: vec!["/foo".to_string()], - ..Settings::default() - }, - "S108_extend"; - "S108_2" - )] - fn checks( - check_code: CheckCode, - path: &Path, - plugin_settings: Settings, - label: &str, - ) -> Result<()> { + #[test_case(CheckCode::S101, Path::new("S101.py"); "S101")] + #[test_case(CheckCode::S102, Path::new("S102.py"); "S102")] + #[test_case(CheckCode::S103, Path::new("S103.py"); "S103")] + #[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::S108, Path::new("S108.py"); "S108")] + fn checks(check_code: CheckCode, path: &Path) -> Result<()> { + let snapshot = format!("{}_{}", check_code.as_ref(), path.to_string_lossy()); let checks = test_path( Path::new("./resources/test/fixtures/flake8_bandit") .join(path) .as_path(), - &settings::Settings { - flake8_bandit: plugin_settings, - ..settings::Settings::for_rule(check_code) + &Settings::for_rule(check_code), + )?; + insta::assert_yaml_snapshot!(snapshot, checks); + Ok(()) + } + + #[test] + fn check_hardcoded_tmp_additional_dirs() -> Result<()> { + let checks = test_path( + Path::new("./resources/test/fixtures/flake8_bandit/S108.py"), + &Settings { + flake8_bandit: flake8_bandit::settings::Settings { + hardcoded_tmp_directory: vec![ + "/tmp".to_string(), + "/var/tmp".to_string(), + "/dev/shm".to_string(), + "/foo".to_string(), + ], + }, + ..Settings::for_rule(CheckCode::S108) }, )?; - insta::assert_yaml_snapshot!(label, checks); + insta::assert_yaml_snapshot!("S108_extend", checks); Ok(()) } } diff --git a/src/flake8_bandit/settings.rs b/src/flake8_bandit/settings.rs index 505ce5c33d1c9..d93816de2a4f9 100644 --- a/src/flake8_bandit/settings.rs +++ b/src/flake8_bandit/settings.rs @@ -40,26 +40,16 @@ pub struct Options { #[derive(Debug, Hash)] pub struct Settings { pub hardcoded_tmp_directory: Vec, - pub hardcoded_tmp_directory_extend: Vec, } impl From for Settings { fn from(options: Options) -> Self { + let mut hardcoded_tmp_directory = options + .hardcoded_tmp_directory + .unwrap_or_else(default_tmp_dirs); + hardcoded_tmp_directory.extend(options.hardcoded_tmp_directory_extend.unwrap_or_default()); Self { - hardcoded_tmp_directory: options - .hardcoded_tmp_directory - .unwrap_or_else(default_tmp_dirs), - hardcoded_tmp_directory_extend: options - .hardcoded_tmp_directory_extend - .unwrap_or_default(), - } - } -} -impl From for Options { - fn from(settings: Settings) -> Self { - Self { - hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory), - hardcoded_tmp_directory_extend: Some(settings.hardcoded_tmp_directory_extend), + hardcoded_tmp_directory, } } } @@ -68,16 +58,6 @@ impl Default for Settings { fn default() -> Self { Self { hardcoded_tmp_directory: default_tmp_dirs(), - hardcoded_tmp_directory_extend: Vec::new(), } } } - -impl Settings { - /// Returns an iterator over all directories that are considered temporary. - pub fn all_hardcoded_tmp_directories(&'_ self) -> impl Iterator { - self.hardcoded_tmp_directory - .iter() - .chain(self.hardcoded_tmp_directory_extend.iter()) - } -} diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101_S101.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S101_S101.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102_S102.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S102_S102.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103_S103.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S103_S103.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104_S104.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S104_S104.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105_S105.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S105_S105.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106_S106.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S106_S106.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107_S107.py.snap similarity index 100% rename from src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107.snap rename to src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S107_S107.py.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_S108.py.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_S108.py.snap new file mode 100644 index 0000000000000..cfd8f1c96e86a --- /dev/null +++ b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_S108.py.snap @@ -0,0 +1,35 @@ +--- +source: src/flake8_bandit/mod.rs +expression: checks +--- +- kind: + HardcodedTempFile: /tmp/abc + location: + row: 5 + column: 10 + end_location: + row: 5 + column: 20 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /var/tmp/123 + location: + row: 8 + column: 10 + end_location: + row: 8 + column: 24 + fix: ~ + parent: ~ +- kind: + HardcodedTempFile: /dev/shm/unit/test + location: + row: 11 + column: 10 + end_location: + row: 11 + column: 30 + fix: ~ + parent: ~ + From f8023ffeb4095dae347c4ed39dba5ea25acc1589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Rami=CC=81rez=20Mondrago=CC=81n?= Date: Wed, 4 Jan 2023 20:02:42 -0600 Subject: [PATCH 4/7] Fix `hardcoded_tmp_directory_extend` example --- README.md | 2 +- src/flake8_bandit/settings.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f0e53dc2f420a..202c94ed21bc1 100644 --- a/README.md +++ b/README.md @@ -2395,7 +2395,7 @@ These directories are added to the list in ```toml [tool.ruff.flake8-bandit] -extend_hardcoded_tmp_directory = ["/foo/bar"] +hardcoded_tmp_directory_extend = ["/foo/bar"] ``` --- diff --git a/src/flake8_bandit/settings.rs b/src/flake8_bandit/settings.rs index d93816de2a4f9..309ab7cc004e1 100644 --- a/src/flake8_bandit/settings.rs +++ b/src/flake8_bandit/settings.rs @@ -29,7 +29,7 @@ pub struct Options { #[option( default = "[]", value_type = "Vec", - example = "extend_hardcoded_tmp_directory = [\"/foo/bar\"]" + example = "hardcoded_tmp_directory_extend = [\"/foo/bar\"]" )] /// List of directories that are considered temporary. /// These directories are added to the list in From d0cbb9f90ec0de2cbd426603b5561b2b97020d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Rami=CC=81rez=20Mondrago=CC=81n?= Date: Wed, 4 Jan 2023 20:04:48 -0600 Subject: [PATCH 5/7] Remove old snapshots --- ...f__flake8_bandit__tests__S108_default.snap | 35 ------------------- ...__flake8_bandit__tests__S108_override.snap | 15 -------- 2 files changed, 50 deletions(-) delete mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap delete mode 100644 src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap deleted file mode 100644 index cfd8f1c96e86a..0000000000000 --- a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_default.snap +++ /dev/null @@ -1,35 +0,0 @@ ---- -source: src/flake8_bandit/mod.rs -expression: checks ---- -- kind: - HardcodedTempFile: /tmp/abc - location: - row: 5 - column: 10 - end_location: - row: 5 - column: 20 - fix: ~ - parent: ~ -- kind: - HardcodedTempFile: /var/tmp/123 - location: - row: 8 - column: 10 - end_location: - row: 8 - column: 24 - fix: ~ - parent: ~ -- kind: - HardcodedTempFile: /dev/shm/unit/test - location: - row: 11 - column: 10 - end_location: - row: 11 - column: 30 - fix: ~ - parent: ~ - diff --git a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap b/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap deleted file mode 100644 index 8f29b55446ca4..0000000000000 --- a/src/flake8_bandit/snapshots/ruff__flake8_bandit__tests__S108_override.snap +++ /dev/null @@ -1,15 +0,0 @@ ---- -source: src/flake8_bandit/mod.rs -expression: checks ---- -- kind: - HardcodedTempFile: /foo/bar - location: - row: 15 - column: 10 - end_location: - row: 15 - column: 20 - fix: ~ - parent: ~ - From c10b60c3650fa282865e01564cae6d3fb9c37ea6 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 4 Jan 2023 21:08:50 -0500 Subject: [PATCH 6/7] Tweak docs --- README.md | 11 +++++------ ruff.schema.json | 5 +++-- src/flake8_bandit/settings.rs | 36 ++++++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 88a626bff8047..047c347448a3b 100644 --- a/README.md +++ b/README.md @@ -2367,7 +2367,7 @@ suppress-none-returning = true #### [`hardcoded-tmp-directory`](#hardcoded-tmp-directory) -List of directories that are considered temporary. +A list of directories to consider temporary. **Default value**: `["/tmp", "/var/tmp", "/dev/shm"]` @@ -2377,16 +2377,15 @@ List of directories that are considered temporary. ```toml [tool.ruff.flake8-bandit] -hardcoded_tmp_directory = ["/foo/bar"] +hardcoded-tmp-directory = ["/foo/bar"] ``` --- #### [`hardcoded-tmp-directory-extend`](#hardcoded-tmp-directory-extend) -List of directories that are considered temporary. -These directories are added to the list in -`hardcoded_tmp_directory`. +A list of directories to consider temporary, in addition to those +specified by `hardcoded-tmp-directory`. **Default value**: `[]` @@ -2396,7 +2395,7 @@ These directories are added to the list in ```toml [tool.ruff.flake8-bandit] -hardcoded_tmp_directory_extend = ["/foo/bar"] +extend-hardcoded-tmp-directory = ["/foo/bar"] ``` --- diff --git a/ruff.schema.json b/ruff.schema.json index 28e6624dd1c42..eb6d5720023e9 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -930,6 +930,7 @@ "SIM", "SIM1", "SIM10", + "SIM102", "SIM105", "SIM11", "SIM118", @@ -1098,7 +1099,7 @@ "type": "object", "properties": { "hardcoded-tmp-directory": { - "description": "List of directories that are considered temporary.", + "description": "A list of directories to consider temporary.", "type": [ "array", "null" @@ -1108,7 +1109,7 @@ } }, "hardcoded-tmp-directory-extend": { - "description": "List of directories that are considered temporary. These directories are added to the list in `hardcoded_tmp_directory`.", + "description": "A list of directories to consider temporary, in addition to those specified by `hardcoded-tmp-directory`.", "type": [ "array", "null" diff --git a/src/flake8_bandit/settings.rs b/src/flake8_bandit/settings.rs index 309ab7cc004e1..eb0a76d7794fd 100644 --- a/src/flake8_bandit/settings.rs +++ b/src/flake8_bandit/settings.rs @@ -22,18 +22,17 @@ pub struct Options { #[option( default = "[\"/tmp\", \"/var/tmp\", \"/dev/shm\"]", value_type = "Vec", - example = "hardcoded_tmp_directory = [\"/foo/bar\"]" + example = "hardcoded-tmp-directory = [\"/foo/bar\"]" )] - /// List of directories that are considered temporary. + /// A list of directories to consider temporary. pub hardcoded_tmp_directory: Option>, #[option( default = "[]", value_type = "Vec", - example = "hardcoded_tmp_directory_extend = [\"/foo/bar\"]" + example = "extend-hardcoded-tmp-directory = [\"/foo/bar\"]" )] - /// List of directories that are considered temporary. - /// These directories are added to the list in - /// `hardcoded_tmp_directory`. + /// A list of directories to consider temporary, in addition to those + /// specified by `hardcoded-tmp-directory`. pub hardcoded_tmp_directory_extend: Option>, } @@ -44,12 +43,27 @@ pub struct Settings { impl From for Settings { fn from(options: Options) -> Self { - let mut hardcoded_tmp_directory = options - .hardcoded_tmp_directory - .unwrap_or_else(default_tmp_dirs); - hardcoded_tmp_directory.extend(options.hardcoded_tmp_directory_extend.unwrap_or_default()); Self { - hardcoded_tmp_directory, + hardcoded_tmp_directory: options + .hardcoded_tmp_directory + .unwrap_or_else(default_tmp_dirs) + .into_iter() + .chain( + options + .hardcoded_tmp_directory_extend + .unwrap_or_default() + .into_iter(), + ) + .collect(), + } + } +} + +impl From for Options { + fn from(settings: Settings) -> Self { + Self { + hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory), + hardcoded_tmp_directory_extend: None, } } } From a01ca93a693f6cf01b3c9328c7c55e4efc47b408 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 4 Jan 2023 21:11:03 -0500 Subject: [PATCH 7/7] Rename method to match option --- src/checkers/ast.rs | 2 +- .../{hardcoded_tmp_dir.rs => hardcoded_tmp_directory.rs} | 2 +- src/flake8_bandit/checks/mod.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/flake8_bandit/checks/{hardcoded_tmp_dir.rs => hardcoded_tmp_directory.rs} (77%) diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index 6eca666c1563e..1f596223e9cd6 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -2537,7 +2537,7 @@ where } } if self.settings.enabled.contains(&CheckCode::S108) { - if let Some(check) = flake8_bandit::checks::hardcoded_tmp_dir( + if let Some(check) = flake8_bandit::checks::hardcoded_tmp_directory( expr, value, &self.settings.flake8_bandit.hardcoded_tmp_directory, diff --git a/src/flake8_bandit/checks/hardcoded_tmp_dir.rs b/src/flake8_bandit/checks/hardcoded_tmp_directory.rs similarity index 77% rename from src/flake8_bandit/checks/hardcoded_tmp_dir.rs rename to src/flake8_bandit/checks/hardcoded_tmp_directory.rs index 66a9ea9a91611..d082a4aab8304 100644 --- a/src/flake8_bandit/checks/hardcoded_tmp_dir.rs +++ b/src/flake8_bandit/checks/hardcoded_tmp_directory.rs @@ -4,7 +4,7 @@ use crate::ast::types::Range; use crate::registry::{Check, CheckKind}; /// S108 -pub fn hardcoded_tmp_dir(expr: &Expr, value: &str, prefixes: &[String]) -> Option { +pub fn hardcoded_tmp_directory(expr: &Expr, value: &str, prefixes: &[String]) -> Option { if prefixes.iter().any(|prefix| value.starts_with(prefix)) { Some(Check::new( CheckKind::HardcodedTempFile(value.to_string()), diff --git a/src/flake8_bandit/checks/mod.rs b/src/flake8_bandit/checks/mod.rs index a7777c7a3fbdb..6a1bb66f2256f 100644 --- a/src/flake8_bandit/checks/mod.rs +++ b/src/flake8_bandit/checks/mod.rs @@ -7,7 +7,7 @@ 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 hardcoded_tmp_dir::hardcoded_tmp_dir; +pub use hardcoded_tmp_directory::hardcoded_tmp_directory; mod assert_used; mod bad_file_permissions; @@ -16,4 +16,4 @@ mod hardcoded_bind_all_interfaces; mod hardcoded_password_default; mod hardcoded_password_func_arg; mod hardcoded_password_string; -mod hardcoded_tmp_dir; +mod hardcoded_tmp_directory;