
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
这个SQL, 可以在userName这里注入攻击.
userName : ' or '1'='1
那么整条sql就变成 :
SELECT * FROM users WHERE name = '' or '1'='1';
或者使用注释, 如果后面还有条件的话可以将后面的条件全部注释掉, 适用范围更广.
' or '1'='1' -- '
那么SQL语句变成 :
SELECT * FROM users WHERE name = '' OR '1'='1' -- ';
a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't
那么SQL变成 :
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
statement := "SELECT * FROM userinfo WHERE id = " + a_variable + ";"
SELECT * FROM userinfo WHERE id=1;DROP TABLE users;
select version();
规避举例 :
Java JDBC [edit]
This example uses Java and the JDBC API:
java.sql.PreparedStatement stmt = connection.prepareStatement( "SELECT * FROM users WHERE USERNAME = ? AND ROOM = ?"); stmt.setString(1, username); stmt.setInt(2, roomNumber); stmt.executeQuery();
Java PreparedStatement
provides "setters" (setInt(int), setString(String), setDouble(double),
etc.) for all major built-in data types.
PHP PDO [edit]
This example uses PHP and PHP Data Objects (PDO):
$stmt = $dbh->prepare("SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?"); $stmt->execute(array($username, $password));
PERL DBI [edit]
This example uses Perl and DBI:
my $stmt = $dbh->prepare('SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?'); $stmt->execute($username, $password);
C# ADO.NET [edit]
This example uses C# and ADO.NET:
using (SqlCommand command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM users WHERE USERNAME = @username AND ROOM = @room"; command.Parameters.AddWithValue("@username", username); command.Parameters.AddWithValue("@room", room); using (SqlDataReader dataReader = command.ExecuteReader()) { // ... } }
ADO.NET SqlCommand
will accept any type for the value
parameter of AddWithValue
, and type conversion occurs automatically.
Note the use of "named parameters" (i.e. "@username") rather than "?" - this allows you to use a parameter multiple times and in any arbitrary order within the query command text.
Python DB-API [edit]
This example uses Python DB-API with SQLite and paramstyle='qmark'
:
import sqlite3 conn = sqlite3.connect(':memory:') c = conn.cursor() _users = [('A', 'red'), ('B', 'green'), ('C', 'blue')] c.executemany('INSERT INTO users VALUES (?,?)', _users) params = ('B', 'green') c.execute('SELECT * FROM users WHERE username=? AND room=?', params) c.fetchone()