This commit is contained in:
Ugo Marchand 2025-12-16 16:39:34 -05:00 committed by GitHub
commit fe50869bab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 1 deletions

View File

@ -179,3 +179,10 @@ query63 = t"""
""" """
query64 = f"update {t"{table}"} set var = {t"{var}"}" query64 = f"update {t"{table}"} set var = {t"{var}"}"
query65 = t"update {f"{table}"} set var = {f"{var}"}" query65 = t"update {f"{table}"} set var = {f"{var}"}"
# Implicit string concatenation with binary operation
def query66():
return (
"select * "
"from \"" + schema + "\""
)

View File

@ -73,7 +73,7 @@ pub(crate) fn hardcoded_sql_expression(checker: &Checker, expr: &Expr) {
if is_explicit_concatenation(expr) != Some(true) { if is_explicit_concatenation(expr) != Some(true) {
return; return;
} }
checker.generator().expr(expr) concatenated_binary_string(expr)
} }
// "select * from table where val = %s" % ... // "select * from table where val = %s" % ...
Expr::BinOp(ast::ExprBinOp { Expr::BinOp(ast::ExprBinOp {
@ -136,6 +136,34 @@ fn concatenated_f_string(expr: &ast::ExprFString, locator: &Locator) -> String {
.collect() .collect()
} }
/// Concatenates the contents of a binary string expression.
///
/// ## Example
///
/// ```python
/// "select * " "from table" + var + ";"
/// ```
///
/// becomes `select * from table {} ;`.
fn concatenated_binary_string(expr: &Expr) -> String {
match expr {
Expr::StringLiteral(string_literal) => string_literal.value.to_str().to_string(),
Expr::BinOp(ast::ExprBinOp {
left,
op: Operator::Add,
right,
..
}) => {
format!(
"{}{}",
concatenated_binary_string(left),
concatenated_binary_string(right)
)
}
_ => " {} ".to_string(),
}
}
/// Returns `Some(true)` if an expression appears to be an explicit string concatenation, /// Returns `Some(true)` if an expression appears to be an explicit string concatenation,
/// `Some(false)` if it's _not_ an explicit concatenation, and `None` if it's ambiguous. /// `Some(false)` if it's _not_ an explicit concatenation, and `None` if it's ambiguous.
fn is_explicit_concatenation(expr: &Expr) -> Option<bool> { fn is_explicit_concatenation(expr: &Expr) -> Option<bool> {

View File

@ -672,3 +672,14 @@ S608 Possible SQL injection vector through string-based query construction
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
181 | query65 = t"update {f"{table}"} set var = {f"{var}"}" 181 | query65 = t"update {f"{table}"} set var = {f"{var}"}"
| |
S608 Possible SQL injection vector through string-based query construction
--> S608.py:186:9
|
184 | def query66():
185 | return (
186 | / "select * "
187 | | "from \"" + schema + "\""
| |_________________________________^
188 | )
|