Secure DB Queries
A SQL injection attack is a type of vulnerability where an attacker is able to manipulate a SQL query by injecting user controlled content.
Consider the following code snippet:
$query = $this->db->getQuery(true);
$username = $user->username;
$newPassword = password_hash($newPassword, PASSWORD_DEFAULT);
$query->update('#__users')->set('password = "' . $newPassword . '"')->where('username = "' . $username . '"');
$this->db->setQuery($query)->execute();
The code is supposed to update the password of the currently logged-in user who's identified by his username and the resulting query for the user "foobar" will look like this:
UPDATE jos_users SET password = "{HASH}" WHERE username = "foobar";
Now let's assume that the user chose foobar" OR username="admin
as his username of choice. That would result in a very different query:
UPDATE jos_users SET password = "{HASH}" WHERE username = "foobar" OR username="admin";
So, the attacker has injected his user controlled commands in the query, resetting not only his password but also the password of the admin user.
Prevention
Use prepared statements
This is the gold standard to prevent SQLi attacks.
The basic principle is simple: instead of integrating the user provided values in the query within the PHP code, query and input values are sent to the DB server in separate calls:
Prepared Statements
Query: SELECT foobar FROM bar WHERE foo = ?
Data: [? = 'bar']
The basic principle is simple: instead of integrating the user provided values in the query within the PHP code, query and input values are sent to the DB server in separate calls. The DB server will then combine queries and values with each other and take care of escaping and/or quotes where necessary.
So, by separating queries and injected values from each other, an injection becomes impossible.