mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge pull request #6727 from RasmusWL/fix-sqlalchemy-query
Python: Merge SQLAlchemy TextClause injection into `py/sql-injection`
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Introduced a new query _SQLAlchemy TextClause built from user-controlled sources_ (`py/sqlalchemy-textclause-injection`) to alert if user-input is added to a TextClause from SQLAlchemy, since that can lead to SQL injection.
|
||||
@@ -0,0 +1,2 @@
|
||||
lgtm,codescanning
|
||||
* Expanded the query _SQL query built from user-controlled sources_ (`py/sql-injection`) to alert if user-input is added to a TextClause from SQLAlchemy, since that can lead to SQL injection.
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration for detecting "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `SQLAlchemyTextClause::Configuration` is needed, otherwise
|
||||
* `SQLAlchemyTextClauseCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
private import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
|
||||
/**
|
||||
* Provides a taint-tracking configuration for detecting "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
module SQLAlchemyTextClause {
|
||||
import SQLAlchemyTextClauseCustomizations::SQLAlchemyTextClause
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for detecting "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SQLAlchemyTextClause" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof SanitizerGuard
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "SQLAlchemy TextClause injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.BarrierGuards
|
||||
private import semmle.python.frameworks.SqlAlchemy
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "SQLAlchemy TextClause injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
module SQLAlchemyTextClause {
|
||||
/**
|
||||
* A data flow source for "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer guard for "SQLAlchemy TextClause injection" vulnerabilities.
|
||||
*/
|
||||
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
/**
|
||||
* A source of remote user input, considered as a flow source.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* The text argument of a SQLAlchemy TextClause construction, considered as a flow sink.
|
||||
*/
|
||||
class TextArgAsSink extends Sink {
|
||||
TextArgAsSink() { this = any(SqlAlchemy::TextClause::TextClauseConstruction tcc).getTextArg() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison with a constant string, considered as a sanitizer-guard.
|
||||
*/
|
||||
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }
|
||||
}
|
||||
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.BarrierGuards
|
||||
private import semmle.python.frameworks.SqlAlchemy
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
@@ -48,6 +49,13 @@ module SqlInjection {
|
||||
SqlExecutionAsSink() { this = any(SqlExecution e).getSql() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The text argument of a SQLAlchemy TextClause construction, considered as a flow sink.
|
||||
*/
|
||||
class TextArgAsSink extends Sink {
|
||||
TextArgAsSink() { this = any(SqlAlchemy::TextClause::TextClauseConstruction tcc).getTextArg() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison with a constant string, considered as a sanitizer-guard.
|
||||
*/
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
The <code>TextClause</code> class in the <code>SQLAlchemy</code> PyPI package represents
|
||||
a textual SQL string directly. If user-input is added to it without sufficient
|
||||
sanitization, a user may be able to run malicious database queries, since the
|
||||
<code>TextClause</code> is inserted directly into the final SQL.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Don't allow user-input to be added to a <code>TextClause</code>, instead construct your
|
||||
full query with constructs from the ORM, or use query parameters for user-input.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following snippet, a user is fetched from the database using three
|
||||
different queries.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the first case, the final query string is built by directly including a user-supplied
|
||||
input. The parameter may include quote characters, so this code is vulnerable to a SQL
|
||||
injection attack.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the second case, the query is built using ORM models, but part of it is using a
|
||||
<code>TextClause</code> directly including a user-supplied input. Since the
|
||||
<code>TextClause</code> is inserted directly into the final SQL, this code is vulnerable
|
||||
to a SQL injection attack.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the third case, the query is built fully using the ORM models, so in the end, the
|
||||
user-supplied input will be passed to the database using query parameters. The
|
||||
database connector library will take care of escaping and inserting quotes as needed.
|
||||
</p>
|
||||
|
||||
<sample src="examples/sqlalchemy_textclause_injection.py" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li><a href="https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.text.params.text">Official documentation of the text parameter</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* @name SQLAlchemy TextClause built from user-controlled sources
|
||||
* @description Building a TextClause query from user-controlled sources is vulnerable to insertion of
|
||||
* malicious SQL code by the user.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 8.8
|
||||
* @precision high
|
||||
* @id py/sqlalchemy-textclause-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-089
|
||||
* external/owasp/owasp-a1
|
||||
*/
|
||||
|
||||
import python
|
||||
import semmle.python.security.dataflow.SQLAlchemyTextClause
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from SQLAlchemyTextClause::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"This SQLAlchemy TextClause depends on $@, which could lead to SQL injection.", source.getNode(),
|
||||
"a user-provided value"
|
||||
@@ -9,6 +9,13 @@ If a database query (such as a SQL or NoSQL query) is built from
|
||||
user-provided data without sufficient sanitization, a user
|
||||
may be able to run malicious database queries.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This also includes using the <code>TextClause</code> class in the
|
||||
<code><a href="https://pypi.org/project/SQLAlchemy/">SQLAlchemy</a></code> PyPI package,
|
||||
which is used to represent a literal SQL fragment and is inserted directly into the
|
||||
final SQL when used in a query built using the ORM.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
@@ -52,5 +59,6 @@ vulnerable to SQL injection attacks. In this example, if <code>username</code> w
|
||||
<references>
|
||||
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</li>
|
||||
<li>OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html">SQL Injection Prevention Cheat Sheet</a>.</li>
|
||||
<li><a href="https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.text.params.text">SQLAlchemy documentation for TextClause</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
from flask import Flask, request
|
||||
import sqlalchemy
|
||||
import sqlalchemy.orm
|
||||
|
||||
app = Flask(__name__)
|
||||
engine = sqlalchemy.create_engine(...)
|
||||
Base = sqlalchemy.orm.declarative_base()
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
|
||||
username = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
|
||||
@app.route("/users/<username>")
|
||||
def show_user(username):
|
||||
session = sqlalchemy.orm.Session(engine)
|
||||
|
||||
# BAD, normal SQL injection
|
||||
stmt = sqlalchemy.text("SELECT * FROM users WHERE username = '{}'".format(username))
|
||||
results = session.execute(stmt).fetchall()
|
||||
|
||||
# BAD, allows SQL injection
|
||||
username_formatted_for_sql = sqlalchemy.text("'{}'".format(username))
|
||||
stmt = sqlalchemy.select(User).where(User.username == username_formatted_for_sql)
|
||||
results = session.execute(stmt).scalars().all()
|
||||
|
||||
# GOOD, does not allow for SQL injection
|
||||
stmt = sqlalchemy.select(User).where(User.username == username)
|
||||
results = session.execute(stmt).scalars().all()
|
||||
|
||||
...
|
||||
@@ -1,41 +0,0 @@
|
||||
edges
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:27:28:27:87 | ControlFlowNode for Attribute() |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:31:50:31:72 | ControlFlowNode for Attribute() |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:41:26:41:33 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:42:31:42:38 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:43:30:43:37 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:44:35:44:42 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:45:41:45:48 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:46:46:46:53 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:47:47:47:54 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:48:52:48:59 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:50:18:50:25 | ControlFlowNode for username |
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | test.py:51:24:51:31 | ControlFlowNode for username |
|
||||
nodes
|
||||
| test.py:23:15:23:22 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:27:28:27:87 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:31:50:31:72 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:41:26:41:33 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:42:31:42:38 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:43:30:43:37 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:44:35:44:42 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:45:41:45:48 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:46:46:46:53 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:47:47:47:54 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:48:52:48:59 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:50:18:50:25 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| test.py:51:24:51:31 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
subpaths
|
||||
#select
|
||||
| test.py:27:28:27:87 | ControlFlowNode for Attribute() | test.py:23:15:23:22 | ControlFlowNode for username | test.py:27:28:27:87 | ControlFlowNode for Attribute() | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:31:50:31:72 | ControlFlowNode for Attribute() | test.py:23:15:23:22 | ControlFlowNode for username | test.py:31:50:31:72 | ControlFlowNode for Attribute() | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:41:26:41:33 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:41:26:41:33 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:42:31:42:38 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:42:31:42:38 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:43:30:43:37 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:43:30:43:37 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:44:35:44:42 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:44:35:44:42 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:45:41:45:48 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:45:41:45:48 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:46:46:46:53 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:46:46:46:53 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:47:47:47:54 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:47:47:47:54 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:48:52:48:59 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:48:52:48:59 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:50:18:50:25 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:50:18:50:25 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| test.py:51:24:51:31 | ControlFlowNode for username | test.py:23:15:23:22 | ControlFlowNode for username | test.py:51:24:51:31 | ControlFlowNode for username | This SQLAlchemy TextClause depends on $@, which could lead to SQL injection. | test.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
Security/CWE-089/SQLAlchemyTextClauseInjection.ql
|
||||
@@ -3,15 +3,52 @@ edges
|
||||
| sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username |
|
||||
nodes
|
||||
| sql_injection.py:14:15:14:22 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
| sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
|
||||
subpaths
|
||||
#select
|
||||
| sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
| sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value |
|
||||
|
||||
Reference in New Issue
Block a user