Link Search Menu Expand Document

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

OWASP - SQL Injection

OWASP - SQL Injection Prevention Cheat Sheet