SQL Injection in Go Lang
Vulnerable example
The following snippet contains a Go Lang application that runs an SQL query to resolve the host supplied by the user.
customerId := r.URL.Query().Get("id")
query := "SELECT account_number, account_balance FROM customer_data WHERE account_owner_id = " + customerId
rows, err := db.Query(query)
Since the SQL query is built concatenating id
user inputs, an attacker could manipulate the query to disclose other people’s data and even affect the integrity of the database, depending on the database engine in use.
For example, by supplying 123 OR 1=1;--
in the id
field, the SQL query becomes:
SELECT account_number, account_balance FROM customer_data WHERE account_owner_id = 123 OR 1=1;--
The manipulated query returns any entry in the customer_data
table that has an owner id 123
or if 1
equals 1
. The query statement is then terminated, commenting out any trailing code using ;--
. Since the WHERE
statement is always true, the query returns all of the orders of all of the customers.
Prevention
Go Lang provides the DB.Prepare
method in the database/sql
package (reference here). The method allows parameterized queries to be performed on most of the database technologies available. Please reference the code below which shows how to refactor the vulnerable code showed above using parameterized statements.
customerId := r.URL.Query().Get("id")
stmt, err := db.Prepare("SELECT account_number, account_balance FROM customer_data WHERE account_owner_id = ?")
rows, err := stmt.Query(customerId)
References
CWE - CWE-89: Improper Neutralization of Special Elements used in an SQL Command