Skip to content

Commit

Permalink
[flake8-bandit] Add Rule for S702 (use of mako templates)
Browse files Browse the repository at this point in the history
  • Loading branch information
ischaojie committed Nov 7, 2023
1 parent 5e2bb8c commit c1f4a68
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 0 deletions.
11 changes: 11 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_bandit/S702.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from mako.template import Template
import mako

from mako import template

Template("hello")

# XXX(fletcher): for some reason, bandit is missing the one below. keeping it
# in for now so that if it gets fixed inadvertitently we know.
mako.template.Template("hern")
template.Template("hern")
3 changes: 3 additions & 0 deletions crates/ruff_linter/src/checkers/ast/analyze/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
if checker.enabled(Rule::Jinja2AutoescapeFalse) {
flake8_bandit::rules::jinja2_autoescape_false(checker, call);
}
if checker.enabled(Rule::MakoTemplates) {
flake8_bandit::rules::mako_templates(checker, call);
}
if checker.enabled(Rule::HardcodedPasswordFuncArg) {
flake8_bandit::rules::hardcoded_password_func_arg(checker, keywords);
}
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Flake8Bandit, "609") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnixCommandWildcardInjection),
(Flake8Bandit, "612") => (RuleGroup::Stable, rules::flake8_bandit::rules::LoggingConfigInsecureListen),
(Flake8Bandit, "701") => (RuleGroup::Stable, rules::flake8_bandit::rules::Jinja2AutoescapeFalse),
(Flake8Bandit, "702") => (RuleGroup::Stable, rules::flake8_bandit::rules::MakoTemplates),

// flake8-boolean-trap
(Flake8BooleanTrap, "001") => (RuleGroup::Stable, rules::flake8_boolean_trap::rules::BooleanTypeHintPositionalArgument),
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/rules/flake8_bandit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod tests {
#[test_case(Rule::HardcodedTempFile, Path::new("S108.py"))]
#[test_case(Rule::HashlibInsecureHashFunction, Path::new("S324.py"))]
#[test_case(Rule::Jinja2AutoescapeFalse, Path::new("S701.py"))]
#[test_case(Rule::MakoTemplates, Path::new("S702.py"))]
#[test_case(Rule::LoggingConfigInsecureListen, Path::new("S612.py"))]
#[test_case(Rule::ParamikoCall, Path::new("S601.py"))]
#[test_case(Rule::RequestWithNoCertValidation, Path::new("S501.py"))]
Expand Down
59 changes: 59 additions & 0 deletions crates/ruff_linter/src/rules/flake8_bandit/rules/mako_templates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::checkers::ast::Checker;
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast};
use ruff_text_size::Ranged;

/// ## What it does
/// Checks for uses of the `mako` templates.
///
/// ## Why is this bad?
/// Mako templates allow HTML/JS rendering by default and are
/// inherently open to XSS attacks. Ensure variables in all templates are
/// properly sanitized via the 'n', 'h' or 'x' flags (depending on context).
/// For example, to HTML escape the variable 'data' do ${ data |h }.
///
/// ## Example
/// ```python
/// from mako.template import Template
///
/// Template("hello")
/// ```
///
/// Use instead:
/// ```python
/// from mako.template import Template
///
/// Template("hello |h")
/// ```
///
/// ## References
/// - [Mako documentation](https://www.makotemplates.org/)
/// - [OpenStack security: Cross site scripting XSS](https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html)
/// - [Common Weakness Enumeration: CWE-80](https://cwe.mitre.org/data/definitions/80.html)
#[violation]
pub struct MakoTemplates;

impl Violation for MakoTemplates {
#[derive_message_formats]
fn message(&self) -> String {
format!(
"Mako templates allow HTML/JS rendering by default and are inherently open to XSS attacks.\
Ensure variables in all templates are properly sanitized via the 'n', 'h' or 'x' flags (depending on context).\
For example, to HTML escape the variable 'data' do ${{ data |h }}."
)
}
}

/// S702
pub(crate) fn mako_templates(checker: &mut Checker, call: &ast::ExprCall) {
if checker
.semantic()
.resolve_call_path(&call.func)
.is_some_and(|call_path| matches!(call_path.as_slice(), ["mako", "template", "Template"]))
{
checker
.diagnostics
.push(Diagnostic::new(MakoTemplates, call.func.range()));
}
}
2 changes: 2 additions & 0 deletions crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) use hardcoded_tmp_directory::*;
pub(crate) use hashlib_insecure_hash_functions::*;
pub(crate) use jinja2_autoescape_false::*;
pub(crate) use logging_config_insecure_listen::*;
pub(crate) use mako_templates::*;
pub(crate) use paramiko_calls::*;
pub(crate) use request_with_no_cert_validation::*;
pub(crate) use request_without_timeout::*;
Expand All @@ -37,6 +38,7 @@ mod hardcoded_tmp_directory;
mod hashlib_insecure_hash_functions;
mod jinja2_autoescape_false;
mod logging_config_insecure_listen;
mod mako_templates;
mod paramiko_calls;
mod request_with_no_cert_validation;
mod request_without_timeout;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs
---
S702.py:6:1: S702 Mako templates allow HTML/JS rendering by default and are inherently open to XSS attacks.Ensure variables in all templates are properly sanitized via the 'n', 'h' or 'x' flags (depending on context).For example, to HTML escape the variable 'data' do ${ data |h }.
|
4 | from mako import template
5 |
6 | Template("hello")
| ^^^^^^^^ S702
7 |
8 | # XXX(fletcher): for some reason, bandit is missing the one below. keeping it
|

S702.py:10:1: S702 Mako templates allow HTML/JS rendering by default and are inherently open to XSS attacks.Ensure variables in all templates are properly sanitized via the 'n', 'h' or 'x' flags (depending on context).For example, to HTML escape the variable 'data' do ${ data |h }.
|
8 | # XXX(fletcher): for some reason, bandit is missing the one below. keeping it
9 | # in for now so that if it gets fixed inadvertitently we know.
10 | mako.template.Template("hern")
| ^^^^^^^^^^^^^^^^^^^^^^ S702
11 | template.Template("hern")
|

S702.py:11:1: S702 Mako templates allow HTML/JS rendering by default and are inherently open to XSS attacks.Ensure variables in all templates are properly sanitized via the 'n', 'h' or 'x' flags (depending on context).For example, to HTML escape the variable 'data' do ${ data |h }.
|
9 | # in for now so that if it gets fixed inadvertitently we know.
10 | mako.template.Template("hern")
11 | template.Template("hern")
| ^^^^^^^^^^^^^^^^^ S702
|


1 change: 1 addition & 0 deletions ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c1f4a68

Please sign in to comment.