A SQL injection vulnerability arises when the original SQL query can be altered to form an altogether different query. Execution of this altered query may result in information leaks or data vulnerabilities arise in applications where elements of a SQL query originate from an untrusted source. Without precautions, the untrusted data may maliciously alter the query, resulting in information leaks or data modification. The primary means of preventing SQL injection are sanitizing and : parameterized queries, stored procedures, and sanitizing/validating untrusted input and parameterizing queries.
Suppose a database contains user names and passwords used to authenticate users of the system. A SQL command to authenticate a user might take the following form:system authenticates users by issuing the following query to a SQL database. If the query returns any results, authentication succeeds. Else, authentication fails.
Code Block |
---|
SELECT * FROM db_user WHERE username='<USERNAME>' AND
password='<PASSWORD>'
|
If it returns any records, the user name and password are valid.
Suppose However, if an attacker can substitute arbitrary strings for <USERNAME>
and <PASSWORD>
, he can perform a SQL injection by using the following string for <USERNAME>
:.
Then the authentication mechanism can be bypassed by supplying the following <USERNAME>
, with an arbitrary password.
Code Block |
---|
validuser' OR '1'='1 |
When injected into the command, the command becomesThe authentication routine dynamically constructs the following query.
Code Block |
---|
SELECT * FROM db_user WHERE username='validuser' OR '1'='1' AND password='<PASSWORD>' |
If validuser
is a valid user name, this SELECT
statement selects yields the validuser
record in the table. The The password is never checked because username='validuser'
is true; consequently, the items after the OR
are not tested. As long as the components after the OR
generate a syntactically correct SQL expression, the attacker is granted the access of validuser
.
LikewiseSimilarly, an attacker could supply a the following string for <PASSWORD>
such as, with an arbitrary username:
Code Block |
---|
' OR '1'='1 |
This string would yield Producing the following commandquery:
Code Block |
---|
SELECT * FROM db_user WHERE username='<USERNAME>' AND password='' OR '1'='1'
|
This time, the '1'='1'
tautology disables both user name and password validation, and the attacker is falsely logged in without a correct login ID always evaluates to true, causing the query to yield every row in the database. In this scenario, the attacker would be authenticated without needing a valid username or password.
Noncompliant Code Example
...