概念:在sql语句中需要输入值的地方以参数进行给值
特点:和以往用变量传递拼接出完整的sql语句后再直接执行该语句(拼接后的语句整体会一同参与数据库sql语句的编译过程)不同的是:值的给定会在数据库编译完sql语句后,也就是说,参数中的值并不参与sql语句的编译过程,自然其中的语句就无法被执行,也就避免了sql注入
现状:不过即使参数化查询被证明可以十分有效的抵御sql注入攻击的情况下,依然有很多网站因为开发不方便或者开发成本提高而不使用参数化查询
需要熟悉各数据库中的变量形式:
假设变量为a1
mysql中的变量形式是?加变量名
例:select * from users where id = ?a1
oracle中的变量形式是:加变量名
例:select * from users where id = :a1
mssql中的变量形式是@加变量名
例:select * from users where id = @a1
dvwa靶场sql注入的impossible级别就使用了参数化查询
<?php if( isset( $_GET[ 'Submit' ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Get input $id = $_GET[ 'id' ]; // Was a number entered? if(is_numeric( $id )) { // Check the database $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' ); $data->bindParam( ':id', $id, PDO::PARAM_INT ); $data->execute(); $row = $data->fetch(); // Make sure only 1 result is returned if( $data->rowCount() == 1 ) { // Get values $first = $row[ 'first_name' ]; $last = $row[ 'last_name' ]; // Feedback for end user echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>"; } } } // Generate Anti-CSRF token generateSessionToken(); ?>
(记笔记加深印象,写的不对请随便喷,嘿嘿)