help:sql_injection_sqli
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
help:sql_injection_sqli [2016/10/12 08:24] – peter | help:sql_injection_sqli [2020/07/22 17:55] (current) – old revision restored (2016/10/13 15:20) 207.244.157.10 | ||
---|---|---|---|
Line 4: | Line 4: | ||
Injection flaws occur when an application sends untrusted data to an interpreter. | Injection flaws occur when an application sends untrusted data to an interpreter. | ||
+ | |||
+ | [[SQL Injection: | ||
+ | |||
+ | [[SQL Injection: | ||
[[SQL Injection: | [[SQL Injection: | ||
Line 9: | Line 13: | ||
[[SQL Injection: | [[SQL Injection: | ||
+ | [[SQL Injection: | ||
- | ===== Primary Defenses ===== | + | [[SQL Injection:Why not to use escape quotes as a defence|Why not to use escape quotes as a defence]] |
- | + | ||
- | * Use Prepared Statements (Parameterized Queries) | + | |
- | * Use Stored Procedures | + | |
- | * Escape all User Supplied Input | + | |
- | + | ||
- | + | ||
- | ===== Prepared Statements ===== | + | |
- | + | ||
- | The use of prepared statements with variable binding (aka parameterized queries) is how all developers should first be taught how to write database queries. | + | |
- | + | ||
- | Prepared statements ensure that an attacker is not able to change the intent of a query, even if SQL commands are inserted by an attacker. | + | |
- | + | ||
- | + | ||
- | ==== PHP ==== | + | |
- | + | ||
- | === Using mysqli === | + | |
- | + | ||
- | The MySQL Improved extension handles bound parameters. | + | |
- | + | ||
- | <code php> | + | |
- | $stmt = $db-> | + | |
- | $stmt-> | + | |
- | $stmt-> | + | |
- | </ | + | |
- | + | ||
- | === Using ADODB === | + | |
- | + | ||
- | ADODB provides a way to prepare, bind and execute all in the same method call. | + | |
- | + | ||
- | <code php> | + | |
- | $dbConnection = NewADOConnection($connectionString); | + | |
- | $sqlResult = $dbConnection-> | + | |
- | ' | + | |
- | array($_REQUEST[' | + | |
- | ); | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | === Using the ODBC layer === | + | |
- | + | ||
- | <code php> | + | |
- | $stmt = odbc_prepare( $conn, ' | + | |
- | $success = odbc_execute( $stmt, array($email) ); | + | |
- | </ | + | |
- | + | ||
- | or: | + | |
- | + | ||
- | <code php> | + | |
- | $res = odbc_exec($conn, | + | |
- | $sth = $dbh-> | + | |
- | $sth-> | + | |
- | </ | + | |
- | + | ||
- | === Using the PDO layer === | + | |
- | + | ||
- | Here's the long way to do bind parameters. | + | |
- | + | ||
- | <code php> | + | |
- | $dbh = new PDO(' | + | |
- | $stmt = $dbh-> | + | |
- | $stmt-> | + | |
- | $stmt-> | + | |
- | + | ||
- | // insert one row | + | |
- | $name = ' | + | |
- | $value = 1; | + | |
- | $stmt-> | + | |
- | </ | + | |
- | + | ||
- | And a shorter way to pass things in. | + | |
- | + | ||
- | <code php> | + | |
- | $dbh = new PDO(' | + | |
- | $stmt = $dbh-> | + | |
- | $stmt-> | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | === Using PostgreSQL === | + | |
- | + | ||
- | <code php> | + | |
- | $result = pg_query_params( $dbh, ' | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ==== Java ==== | + | |
- | + | ||
- | === JDBC === | + | |
- | + | ||
- | The JDBC API has a class called PreparedStatement which allows the programmer to safely insert user-supplied data into a SQL query. The location of each input value in the query string is marked with a question mark. The various set*() methods are then used to safely perform the insertion. | + | |
- | + | ||
- | <code jaVA> | + | |
- | String name = //user input | + | |
- | int age = //user input | + | |
- | Connection connection = DriverManager.getConnection(...); | + | |
- | PreparedStatement statement = connection.prepareStatement( | + | |
- | " | + | |
- | statement.setString(1, | + | |
- | statement.setInt(2, | + | |
- | ResultSet rs = statement.executeQuery(); | + | |
- | while (rs.next()){ | + | |
- | //... | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | === Hibernate === | + | |
- | + | ||
- | Hibernate uses named parameters to safely insert data into a query. A named parameter consists of a colon, followed by a unique name for the parameter. | + | |
- | + | ||
- | <code java> | + | |
- | String name = //user input | + | |
- | int age = //user input | + | |
- | Session session = //... | + | |
- | Query query = session.createQuery(" | + | |
- | query.setString(" | + | |
- | query.setInteger(" | + | |
- | Iterator people = query.iterate(); | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ==== Perl ==== | + | |
- | + | ||
- | Perl's DBI, available on the CPAN, supports parameterized SQL calls. Both the do method and prepare method support parameters (" | + | |
- | + | ||
- | <code perl> | + | |
- | $sth = $dbh-> | + | |
- | foreach my $email (@emails) { | + | |
- | $sth-> | + | |
- | $row = $sth-> | + | |
- | [...] | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | However, you can't use parameterization for identifiers (table names, column names) so you need to use DBI's quote_identifier() method for that: | + | |
- | + | ||
- | <code perl> | + | |
- | # Make sure a table name we want to use is safe: | + | |
- | my $quoted_table_name = $dbh-> | + | |
- | + | ||
- | # Assume @cols contains | + | |
- | my $cols = join ',', | + | |
- | + | ||
- | my $sth = $dbh-> | + | |
- | </ | + | |
- | + | ||
- | You could also avoid writing SQL by hand by using DBIx:: | + | |
- | + | ||
- | + | ||
- | ==== SQLite ==== | + | |
- | + | ||
- | Use **sqlite3_prepare()** to create a statement object. | + | |
- | ===== References ===== | ||
- | http:// |
help/sql_injection_sqli.1476260677.txt.gz · Last modified: 2020/07/15 09:30 (external edit)