Summary
The Archery project contains multiple SQL injection vulnerabilities, that may allow an attacker to query the connected databases.
Product
Archery
Tested Version
v1.9.0
Details
SQL injection exists in the project due to unsafe user input being concatenated with a SQL query, that is passed to methods executing a query in a database. All identified issues exist due to the controller files in folder sql
taking user input and not sanitizing it, which later is passed to execution. Since the controller methods are connected to and allows querying all the databases that are connected to Archery, then all databases making queries with concatenated input will be affected. In this way, one vulnerable endpoint allows for exploiting several databases. To exploit most of these SQL injections, knowledge of the exploited instance name that is defined in Archery, is needed.
Issue 1: SQL injection in sql/instance.py
endpoint describe
method (GHSL-2022-101
)
In several below listed cases, user input coming from the tb_name
parameter value, db_name
parameter value or schema_name
in the sql/instance.py
> describe
endpoint is passed to the below defined describe_table
methods in given SQL engine implementations, which concatenate user input unsafely into a SQL query and afterwards pass it to the query
method of each database engine for execution. Please take into account that in some cases all three parameter values are concatenated, in other only one or two of them.
Remediation
Escape the variables accepting user input in in sql/instance.py
endpoint describe
method, that is tb_name
, db_name
and schema_name
by using f.ex. MySQLdb.escape(). This solution is easier to implement and will fix the issues in all SQL engines at once.
Impact
All of the issues may lead to Information Disclosure
.
General remediation advice
To fix each of the issues, the best practice would be to escape the user input (as presented in Remediation
section of each of the issues) or use prepared statements when executing SQL queries. Using placeholders in cursor.execute() will automatically escape the passed values. See Django documentation around executing custom SQL directly and Connections and cursors.
Generally, it is best to use prepared statements rather, but for Archery's codebase it would be much easier to fix the issues by escaping user input, which is sufficient protection. Please consider also escaping all other variables which accept input from the user, particularly the ones from GET or POST requests.
For more information on preventing SQL injection see SQL Injection Prevention Cheat Sheet - Primary Defenses
Credit
These issues were discovered and reported by GHSL team member @sylwia-budzynska (Sylwia Budzynska).
Disclosure Policy
This report is subject to our coordinated disclosure policy.
Summary
The Archery project contains multiple SQL injection vulnerabilities, that may allow an attacker to query the connected databases.
Product
Archery
Tested Version
v1.9.0
Details
SQL injection exists in the project due to unsafe user input being concatenated with a SQL query, that is passed to methods executing a query in a database. All identified issues exist due to the controller files in folder
sql
taking user input and not sanitizing it, which later is passed to execution. Since the controller methods are connected to and allows querying all the databases that are connected to Archery, then all databases making queries with concatenated input will be affected. In this way, one vulnerable endpoint allows for exploiting several databases. To exploit most of these SQL injections, knowledge of the exploited instance name that is defined in Archery, is needed.Issue 1: SQL injection in
sql/instance.py
endpointdescribe
method (GHSL-2022-101
)In several below listed cases, user input coming from the
tb_name
parameter value,db_name
parameter value orschema_name
in thesql/instance.py
>describe
endpoint is passed to the below defineddescribe_table
methods in given SQL engine implementations, which concatenate user input unsafely into a SQL query and afterwards pass it to thequery
method of each database engine for execution. Please take into account that in some cases all three parameter values are concatenated, in other only one or two of them.sql/engines/clickhouse.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/clickhouse.py
>query
methodsql/engines/mssql.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/mssql.py
>query
method in line 310 and line 311sql/engines/mysql.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/mysql.py
>query
methodsql/engines/oracle.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/oracle.py
>query
method in line 640, line 645 and line 647sql/engines/pgsql.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/pgsql.py
>query
method on line 182 and line 183sql/engines/phoenix.py
>describe_table
method concatenates input which is passed to execution on the database in thesql/engines/phoenix.py
>query
methodRemediation
Escape the variables accepting user input in in
sql/instance.py
endpointdescribe
method, that istb_name
,db_name
andschema_name
by using f.ex. MySQLdb.escape(). This solution is easier to implement and will fix the issues in all SQL engines at once.Impact
All of the issues may lead to
Information Disclosure
.General remediation advice
To fix each of the issues, the best practice would be to escape the user input (as presented in
Remediation
section of each of the issues) or use prepared statements when executing SQL queries. Using placeholders in cursor.execute() will automatically escape the passed values. See Django documentation around executing custom SQL directly and Connections and cursors.Generally, it is best to use prepared statements rather, but for Archery's codebase it would be much easier to fix the issues by escaping user input, which is sufficient protection. Please consider also escaping all other variables which accept input from the user, particularly the ones from GET or POST requests.
For more information on preventing SQL injection see SQL Injection Prevention Cheat Sheet - Primary Defenses
Credit
These issues were discovered and reported by GHSL team member @sylwia-budzynska (Sylwia Budzynska).
Disclosure Policy
This report is subject to our coordinated disclosure policy.