是否可以设置URL的参数查询?

Is it possible to set parameter query of the URL?

我想知道开发人员是否可以设置 url 的参数化查询 来缓解 SQL 注入漏洞?

例如:

https://example.com/somefile.php?id=1

开发人员如何为此进行参数化查询?就像他们在应用程序的参数中那样做?

是的,你可以做到。参数化查询很简单,它强制您预先定义 SQL 查询,并在查询中为用户提供的变量使用占位符。然后你可以在定义了SQL语句之后将每个参数传入查询,让数据库能够区分SQL命令和用户输入的数据。如果 SQL 命令由攻击者输入,参数化查询会将这些视为不受信任的输入,注入的 SQL 命令将永远不会执行。请注意下面提供的示例以获得更多理解。

if (isset($_GET['id'])){
  $id = $_GET['id'];
  /**
   * Validate data before it enters the database. In this case, we need to check that
   * the value of the 'id' GET parameter is numeric
   */
   if ( is_numeric($id) == true){
    try{ 
      $dbh = new PDO('mysql:host=localhost;dbname=sql_injection_example', 'dbuser', 'dbpasswd');

      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

      /**
       * Before executing our SQL statement, we need to prepare it by 'binding' parameters.
       * We will bind our validated user input (in this case, it's the value of $id) to our
       * SQL statement before sending it to the database server.
       *
       * This fixes the SQL injection vulnerability.
       */
      $q = "SELECT username 
          FROM users
          WHERE id = :id";
      // Prepare the SQL query
      $sth = $dbh->prepare($q);
      // Bind parameters to statement variables
      $sth->bindParam(':id', $id);
      // Execute statement
      $sth->execute();

      $sth->setFetchMode(PDO::FETCH_ASSOC);
      // Fetch result
      $result = $sth->fetchColumn();
      /**
       * HTML encode our result using htmlentities() to prevent stored XSS and print the
       * result to the page
       */
      print( htmlentities($result) );

      $dbh = null;
    }
    catch(PDOException $e){
      /**
       * You can log PDO exceptions to PHP's system logger, using the Operating System's
       * system logging mechanism
       *
       * For more logging options visit http://php.net/manual/en/function.error-log.php
       */
      error_log('PDOException - ' . $e->getMessage(), 0);
      /**
       * Stop executing, return an 'Internal Server Error' HTTP status code (500),
       * and display an error
       */
      http_response_code(500);
      die('Error establishing connection with database');
    }
   } else{
    /**
     * If the value of the 'id' GET parameter is not numeric, stop executing, return
     * a 'Bad request' HTTP status code (400), and display an error
     */
    http_response_code(400);
    die('Error processing bad or malformed request');
   }
}
?>

问题不在 URL 中,而是稍后如何使用 URL 中传递的参数。

最好的方法是使用绑定变量:

  • How do prepared statements help us prevent SQL injection attacks?.
  • How can I prevent SQL injection in PHP?

您还可以通过转义 and/or 删除可疑数据来“处理”或 'sanitize' 您的参数。这通常是一件非常棘手的事情,容易出错。因此绑定变量使用起来更简单、更安全。