SQL injection

Separate input values from SQL syntax with parameter binding

Description

SQL injection occurs when external input is interpreted as SQL syntax rather than data. An attacker can change a query's conditions or operations. The impact depends on the database account's permissions and available features.

Potential impact

  • Operating-system command execution where database features and permissions permit it
  • Disclosure of sensitive database records
  • Impersonation or privilege escalation
  • Bypass of authentication and access controls
  • Unauthorized data modification or deletion

Remediation

  1. Separate values from SQL syntax with PreparedStatement or JdbcTemplate parameter binding. Preparing SQL after concatenating input is insufficient.
  2. ORM use alone does not protect concatenated SQL, JPQL or HQL. Use the supported binding APIs.
  3. Select table names, column names and sort directions from a server-owned allow-list when they cannot be expressed as value parameters.
  4. Validate input format and length, and grant the database account only necessary permissions.

Examples

These JdbcTemplate excerpts retrieve user records; they do not implement login. Perform password verification and authorization to read the records separately.

Before

java
String query = "SELECT id, username FROM users WHERE username = '" + username + "'";
jdbcTemplate.queryForList(query);

After

java
String query = "SELECT id, username FROM users WHERE username = ?";
jdbcTemplate.queryForList(query, username);

The first concatenates username into SQL. The second supplies the value separately to the query API, queryForList(), so it is not interpreted as SQL syntax.

Related CVEs

References