mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Add documentation to the S1XX
rules (#5479)
## Summary Add documentation to the `S1XX` rules (the `flake8-bandit` ['misc tests'](https://bandit.readthedocs.io/en/latest/plugins/index.html#plugin-id-groupings) rule group). ## Test Plan `python scripts/check_docs_formatted.py && mkdocs serve`
This commit is contained in:
parent
cc822082a7
commit
3650aaa8b3
10 changed files with 266 additions and 3 deletions
|
@ -9,6 +9,31 @@ use ruff_python_semantic::SemanticModel;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for files with overly permissive permissions.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Overly permissive file permissions may allow unintended access and
|
||||||
|
/// arbitrary code execution.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// import os
|
||||||
|
///
|
||||||
|
/// os.chmod("/etc/secrets.txt", 0o666) # rw-rw-rw-
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import os
|
||||||
|
///
|
||||||
|
/// os.chmod("/etc/secrets.txt", 0o600) # rw-------
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Python documentation: `os.chmod`](https://docs.python.org/3/library/os.html#os.chmod)
|
||||||
|
/// - [Python documentation: `stat`](https://docs.python.org/3/library/stat.html)
|
||||||
|
/// - [Common Weakness Enumeration: CWE-732](https://cwe.mitre.org/data/definitions/732.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BadFilePermissions {
|
pub struct BadFilePermissions {
|
||||||
mask: u16,
|
mask: u16,
|
||||||
|
@ -18,7 +43,7 @@ impl Violation for BadFilePermissions {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let BadFilePermissions { mask } = self;
|
let BadFilePermissions { mask } = self;
|
||||||
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory",)
|
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,21 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for uses of the builtin `exec` function.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// The `exec()` function is insecure as it allows for arbitrary code
|
||||||
|
/// execution.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// exec("print('Hello World')")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Python documentation: `exec`](https://docs.python.org/3/library/functions.html#exec)
|
||||||
|
/// - [Common Weakness Enumeration: CWE-78](https://cwe.mitre.org/data/definitions/78.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct ExecBuiltin;
|
pub struct ExecBuiltin;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,27 @@ use ruff_text_size::TextRange;
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for hardcoded bindings to all network interfaces (`0.0.0.0`).
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Binding to all network interfaces is insecure as it allows access from
|
||||||
|
/// unintended interfaces, which may be poorly secured or unauthorized.
|
||||||
|
///
|
||||||
|
/// Instead, bind to specific interfaces.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// ALLOWED_HOSTS = ["0.0.0.0"]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-200](https://cwe.mitre.org/data/definitions/200.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct HardcodedBindAllInterfaces;
|
pub struct HardcodedBindAllInterfaces;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,42 @@
|
||||||
use rustpython_parser::ast::{Arg, ArgWithDefault, Arguments, Expr, Ranged};
|
use rustpython_parser::ast::{Arg, ArgWithDefault, Arguments, Expr, Ranged};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
use super::super::helpers::{matches_password_name, string_literal};
|
use super::super::helpers::{matches_password_name, string_literal};
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for potential uses of hardcoded passwords in function argument
|
||||||
|
/// defaults.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Including a hardcoded password in source code is a security risk, as an
|
||||||
|
/// attacker could discover the password and use it to gain unauthorized
|
||||||
|
/// access.
|
||||||
|
///
|
||||||
|
/// Instead, store passwords and other secrets in configuration files,
|
||||||
|
/// environment variables, or other sources that are excluded from version
|
||||||
|
/// control.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// def connect_to_server(password="hunter2"):
|
||||||
|
/// ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import os
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// def connect_to_server(password=os.environ["PASSWORD"]):
|
||||||
|
/// ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-259](https://cwe.mitre.org/data/definitions/259.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct HardcodedPasswordDefault {
|
pub struct HardcodedPasswordDefault {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
|
@ -1,11 +1,38 @@
|
||||||
use rustpython_parser::ast::{Keyword, Ranged};
|
use rustpython_parser::ast::{Keyword, Ranged};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
use super::super::helpers::{matches_password_name, string_literal};
|
use super::super::helpers::{matches_password_name, string_literal};
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for potential uses of hardcoded passwords in function calls.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Including a hardcoded password in source code is a security risk, as an
|
||||||
|
/// attacker could discover the password and use it to gain unauthorized
|
||||||
|
/// access.
|
||||||
|
///
|
||||||
|
/// Instead, store passwords and other secrets in configuration files,
|
||||||
|
/// environment variables, or other sources that are excluded from version
|
||||||
|
/// control.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// connect_to_server(password="hunter2")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import os
|
||||||
|
///
|
||||||
|
/// connect_to_server(password=os.environ["PASSWORD"])
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-259](https://cwe.mitre.org/data/definitions/259.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct HardcodedPasswordFuncArg {
|
pub struct HardcodedPasswordFuncArg {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
|
@ -7,6 +7,32 @@ use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
use super::super::helpers::{matches_password_name, string_literal};
|
use super::super::helpers::{matches_password_name, string_literal};
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for potential uses of hardcoded passwords in strings.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Including a hardcoded password in source code is a security risk, as an
|
||||||
|
/// attacker could discover the password and use it to gain unauthorized
|
||||||
|
/// access.
|
||||||
|
///
|
||||||
|
/// Instead, store passwords and other secrets in configuration files,
|
||||||
|
/// environment variables, or other sources that are excluded from version
|
||||||
|
/// control.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// SECRET_KEY = "hunter2"
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import os
|
||||||
|
///
|
||||||
|
/// SECRET_KEY = os.environ["SECRET_KEY"]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-259](https://cwe.mitre.org/data/definitions/259.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct HardcodedPasswordString {
|
pub struct HardcodedPasswordString {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
|
@ -3,6 +3,35 @@ use rustpython_parser::ast::{Expr, Ranged};
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for the use of hardcoded temporary file or directory paths.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// The use of hardcoded paths for temporary files can be insecure. If an
|
||||||
|
/// attacker discovers the location of a hardcoded path, they can replace the
|
||||||
|
/// contents of the file or directory with a malicious payload.
|
||||||
|
///
|
||||||
|
/// Other programs may also read or write contents to these hardcoded paths,
|
||||||
|
/// causing unexpected behavior.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// with open("/tmp/foo.txt", "w") as file:
|
||||||
|
/// ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import tempfile
|
||||||
|
///
|
||||||
|
/// with tempfile.NamedTemporaryFile() as file:
|
||||||
|
/// ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-377](https://cwe.mitre.org/data/definitions/377.html)
|
||||||
|
/// - [Common Weakness Enumeration: CWE-379](https://cwe.mitre.org/data/definitions/379.html)
|
||||||
|
/// - [Python documentation: `tempfile`](https://docs.python.org/3/library/tempfile.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct HardcodedTempFile {
|
pub struct HardcodedTempFile {
|
||||||
string: String,
|
string: String,
|
||||||
|
|
|
@ -6,6 +6,31 @@ use ruff_python_ast::helpers::{is_const_none, SimpleCallArgs};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for uses of the Python `requests` module that omit the `timeout`
|
||||||
|
/// parameter.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// The `timeout` parameter is used to set the maximum time to wait for a
|
||||||
|
/// response from the server. By omitting the `timeout` parameter, the program
|
||||||
|
/// may hang indefinitely while awaiting a response.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// import requests
|
||||||
|
///
|
||||||
|
/// requests.get("https://www.example.com/")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import requests
|
||||||
|
///
|
||||||
|
/// requests.get("https://www.example.com/", timeout=10)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Requests documentation: Timeouts](https://requests.readthedocs.io/en/latest/user/advanced/#timeouts)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct RequestWithoutTimeout {
|
pub struct RequestWithoutTimeout {
|
||||||
implicit: bool,
|
implicit: bool,
|
||||||
|
|
|
@ -6,6 +6,40 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::rules::flake8_bandit::helpers::is_untyped_exception;
|
use crate::rules::flake8_bandit::helpers::is_untyped_exception;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for uses of the `try`-`except`-`continue` pattern.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// The `try`-`except`-`continue` pattern suppresses all exceptions.
|
||||||
|
/// Suppressing exceptions may hide errors that could otherwise reveal
|
||||||
|
/// unexpected behavior, security vulnerabilities, or malicious activity.
|
||||||
|
/// Instead, consider logging the exception.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// import logging
|
||||||
|
///
|
||||||
|
/// while predicate:
|
||||||
|
/// try:
|
||||||
|
/// ...
|
||||||
|
/// except Exception:
|
||||||
|
/// continue
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import logging
|
||||||
|
///
|
||||||
|
/// while predicate:
|
||||||
|
/// try:
|
||||||
|
/// ...
|
||||||
|
/// except Exception as exc:
|
||||||
|
/// logging.exception("Error occurred")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-703](https://cwe.mitre.org/data/definitions/703.html)
|
||||||
|
/// - [Python documentation: `logging`](https://docs.python.org/3/library/logging.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct TryExceptContinue;
|
pub struct TryExceptContinue;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,36 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::rules::flake8_bandit::helpers::is_untyped_exception;
|
use crate::rules::flake8_bandit::helpers::is_untyped_exception;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for uses of the `try`-`except`-`pass` pattern.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// The `try`-`except`-`pass` pattern suppresses all exceptions. Suppressing
|
||||||
|
/// exceptions may hide errors that could otherwise reveal unexpected behavior,
|
||||||
|
/// security vulnerabilities, or malicious activity. Instead, consider logging
|
||||||
|
/// the exception.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// try:
|
||||||
|
/// ...
|
||||||
|
/// except Exception:
|
||||||
|
/// pass
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// import logging
|
||||||
|
///
|
||||||
|
/// try:
|
||||||
|
/// ...
|
||||||
|
/// except Exception as exc:
|
||||||
|
/// logging.exception("Exception occurred")
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Common Weakness Enumeration: CWE-703](https://cwe.mitre.org/data/definitions/703.html)
|
||||||
|
/// - [Python documentation: `logging`](https://docs.python.org/3/library/logging.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct TryExceptPass;
|
pub struct TryExceptPass;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue