zoukankan      html  css  js  c++  java
  • 安全 -- mysql参数化查询,防止Mysql注入

    参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击 (SQL Injection) 的攻击手法的防御方式。

    有部份的开发人员可能会认为使用参数化查询,会让程序更不好维护,或者在实现部份功能上会非常不便[来源请求],然而,使用参数化查询造成的额外开发成本,通常都远低于因为SQL注入攻击漏洞被发现而遭受攻击,所造成的重大损失。

    除了安全因素,相比起拼接字符串的 SQL 语句,参数化的查询往往有性能优势。因为参数化的查询能让不同的数据通过参数到达数据库,从而公用同一条 SQL 语句。大多数数据库会缓存解释 SQL 语句产生的字节码而省下重复解析的开销。如果采取拼接字符串的 SQL 语句,则会由于操作数据是 SQL 语句的一部分而非参数的一部分,而反复大量解释 SQL 语句产生不必要的开销。

    MySQL 的参数格式是以 "?" 字符加上参数名称而成。

    UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4

    PDO[编辑]

    PDO用于PHP之内。 在使用 PDO 驱动时,参数查询的使用方法一般为:

    // 实例化数据抽象层对象$db=new PDO('pgsql:host=127.0.0.1;port=5432;dbname=testdb');

    // 对 SQL 语句执行 prepare,得到 PDOStatement 对象

    $stmt=$db->prepare('SELECT * FROM "myTable" WHERE "id" = :id AND "is_valid" = :is_valid');

    // 绑定参数$stmt->bindValue(':id',$id);$stmt->bindValue(':is_valid',true);

    // 查询$stmt->execute();// 获取数据foreach($stmtas$row){var_dump($row);}


    对于 MySQL 的特定驱动,也可以这样使用:

    $db=new mysqli("localhost","user","pass","database");
    
    $stmt=$db->prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
    
    $stmt->bind_param("ss",$user,$pass);$stmt->execute();

    值得注意的是,以下方式虽然能有效防止 SQL注入 (归功于 mysql_real_escape_string 函数的转义),但并不是真正的参数化查询。其本质仍然是拼接字符串的 SQL 语句。

    $query=sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",
    
    mysql_real_escape_string($Username),mysql_real_escape_string($Password));mysql_query($query);
  • 相关阅读:
    JVM内存问题分析
    CAS
    普通内部类,匿名内部类和静态内部类
    文章简介
    conda更换下载源
    MySQL常见约束
    MySQL常见的数据类型
    DDL(数据定义语言)
    DML语言(数据操纵语言)
    进阶9:联合查询
  • 原文地址:https://www.cnblogs.com/mafeng/p/6306096.html
Copyright © 2011-2022 走看看