Php Mysqli_escape_字符串或Prepared语句如何使我免于SQL注入

Php Mysqli_escape_字符串或Prepared语句如何使我免于SQL注入,php,mysqli,prepared-statement,sql-injection,Php,Mysqli,Prepared Statement,Sql Injection,我读了很多关于SQL注入的Stack over flow论坛和答案 我知道这是SQL注入的最基本的层次 $_POST['name'] = 'xyz;DROP Table users'; mysqli_query ('select * from abc where name='."$_POST['name']") 为了防止这种情况 在来自用户的任何输入上使用mysqli\u escape\u stirng可以从SQl注入中拯救我 使用PDO和prepare语句也可以避免SQL注入 问题1

我读了很多关于SQL注入的Stack over flow论坛和答案

我知道这是SQL注入的最基本的层次

  $_POST['name'] = 'xyz;DROP Table users';
  mysqli_query ('select * from abc where name='."$_POST['name']")
为了防止这种情况

  • 在来自用户的任何输入上使用mysqli\u escape\u stirng可以从SQl注入中拯救我
  • 使用PDO和prepare语句也可以避免SQL注入
  • 问题1。这里我想知道的是,如何将数据传递给Mysqli\u escape\u字符串,从而避免SQL注入

      $safe_variable = mysqli_escape_String($connection ,$_POST['name'];
    
      $stmt = $dbh->prepare("select * from ABC where name = :name");
      $stmt->bindParam(':name',$name);
      $name = $_POST['name'];
      $stmt->execute();
    
      $safe_variable = mysqli_escape_String($connection ,$_POST['name'];
    
      $stmt = $dbh->prepare("select * from ABC where name = :name");
      $stmt->bindParam(':name',$name);
      $name = $_POST['name'];
      $stmt->execute();
    
    mysqli_escape_字符串如何仅保存POST数据中的“XYZ”并保留部分的其余部分(如果是这种情况)

    问题2。PDO将如何从SQL注入中拯救我

      $safe_variable = mysqli_escape_String($connection ,$_POST['name'];
    
      $stmt = $dbh->prepare("select * from ABC where name = :name");
      $stmt->bindParam(':name',$name);
      $name = $_POST['name'];
      $stmt->execute();
    
      $safe_variable = mysqli_escape_String($connection ,$_POST['name'];
    
      $stmt = $dbh->prepare("select * from ABC where name = :name");
      $stmt->bindParam(':name',$name);
      $name = $_POST['name'];
      $stmt->execute();
    

    在这方面,他的任何帮助都是值得高度赞赏的

    我认为大多数SQL转义函数都是如此:

    它们逃避了控制字符,如

    那你的绳子呢

    xyz;DROP Table users
    
    将由函数转义到

    xyz\;DROP Table users
    
    因此,您的字符串现在不再是有效的SQL命令

    但是要注意数据库中存储的数据中的HTML标记

    例如,如果我插入

    <script>alert('foobar');</script>
    
    alert('foobar');
    
    这将存储在DB中,不被SQL escape函数处理。如果您再次打印出某个字段,JS将由访问者浏览器执行


    因此,在添加或清理用户输入时使用。对于准备好的语句也是如此。

    我认为大多数SQL转义函数都是这样:

    它们逃避控制字符,如

    那你的绳子呢

    xyz;DROP Table users
    
    将由函数转义到

    xyz\;DROP Table users
    
    因此,您的字符串现在不再是有效的SQL命令

    但是要注意数据库中存储的数据中的HTML标记

    例如,如果我插入

    <script>alert('foobar');</script>
    
    alert('foobar');
    
    这将存储在DB中,不被SQL转义函数处理。如果您再次打印出某个字段,JS将由访问者浏览器执行

    因此,在添加中使用或用于清理用户输入。准备好的报表也是如此。

    Q1:

    mysql(i)\u real\u escape\u string()调用mysql的库函数 mysql(i)\u real\u escape\u字符串,它将反斜杠前置到以下内容 字符:
    \x00
    \n
    \r
    \
    '
    \x1a

    ()

    请注意,这取决于字符编码(本例中的工作是
    集合名称…
    (安全风险!!!),
    $mysqli->SET\u字符集('utf8');
    应该使用!)(您可以在我的帖子中阅读有关编码的内容。)

    它如何防止SQL注入? -它通过转义
    等来防止破坏变量上下文,问题是,
    mysql\u query
    mysqli\u query
    每个查询只执行一个查询,也就是说,它只是忽略
    ;删除表用户

    mysqli\u real\u escape\u string
    不会阻止插入类似于
    DROP DATABASE
    的代码

    在这种情况下,只有PDO和/或
    mysqli_multi_query
    易受攻击

    问题2:

    首先将语句发送到服务器,然后将绑定变量分开发送,然后执行语句。在这种情况下,安全性由数据库库提供,而不是由客户端库提供。您应该更喜欢这样

    这意味着,首先发送
    $dbh->prepare(“从ABC中选择*,其中name=:name”);
    到服务器,数据库知道您的绑定参数将插入到
    :name
    占位符中,并且它将自动正确地包装它,以避免脱离假定的上下文。数据库将尝试查找
    name
    xyz;DROP Table users
    ,并且不会执行任何逗号只需填充变量空间。

    Q1:

    mysql(i)\u real\u escape\u string()调用mysql的库函数 mysql(i)\u real\u escape\u字符串,它将反斜杠前置到以下内容 字符:
    \x00
    \n
    \r
    \
    '
    \x1a

    ()

    请注意,这取决于字符编码(notworkin在本例中是
    集合名称…
    (安全风险!!!),
    $mysqli->SET\u字符集('utf8');应使用
    )。(您可以在我的帖子中阅读有关编码的内容。)

    它如何防止SQL注入? -它通过转义
    等来防止破坏变量上下文,问题是,
    mysql\u query
    mysqli\u query
    每个查询只执行一个查询,也就是说,它只是忽略
    ;删除表格用户

    mysqli\u real\u escape\u string
    不会阻止插入类似于
    DROP DATABASE
    的代码

    在这种情况下,只有PDO和/或
    mysqli_multi_query
    易受攻击

    问题2:

    首先将语句发送到服务器,然后将绑定变量分开发送,然后执行语句。在这种情况下,安全性由数据库库提供,而不是由客户端库提供。你应该更喜欢这个


    这意味着,首先发送
    $dbh->prepare(“从ABC中选择*,其中name=:name”)
    发送到服务器,数据库知道您的绑定参数将插入到
    :name
    占位符中,它将自动正确地包装它,以避免脱离假定的上下文。数据库将尝试查找
    名称
    xyz;删除表用户
    ,它不会执行任何命令,只需填充变量空间。

    将用户输入合并到SQL中的问题是,在生成的SQL中,您无法分辨哪些部分是由开发人员提供的,哪些部分是由用户提供的。这就是为什么开发者必须