【问题标题】:Difficulty passing GET variable?难以传递 GET 变量?
【发布时间】:2012-12-17 16:06:05
【问题描述】:

您好,我正在尝试通过将变量名称附加到如下 URL 来显示数据库中的特定条目:

echo '<td><a class="index_table" href="includes/view.php?id=$row[id]>$row[Orderno]">

然后在我的 view.php 中我有:

<?php
include 'connect.php';
//Display the Data//
$id=$_GET['id']; 
$result=mysql_query("select * from Products where ID=$id");
$row=mysql_fetch_object($result);
echo "<table>";
echo "
<tr bgcolor='#f1f1f1'><td><b>ID</b></td><td>$row->ID</td></tr>

但是,特定的 ID 没有被传递给脚本,并且 view.php 中的表是空白的。将 where 子句更改为 'where id = '1' 时,会显示正确的产品。所以我知道这是有效的。

非常感谢

【问题讨论】:

  • 但我想你是通过 http://site.com/view.php?id=23 访问它的,对吧?
  • @w0rldart 我们都希望如此......
  • 如果我传这个参数怎么办:includes/view.php?id=1%20or%20true
  • 也容易受到sql注入大多数答案都包含SQL注入!小心点!您需要先将 $id 转换为整数!
  • 当我决定将它发送到您的服务器includes/view.php?id=1%3BDROP%20TABLE%20PRODUCTS%3B 时会发生什么?

标签: php html sql get


【解决方案1】:

基本 PHP 语法:用' 引用的字符串不会插入变量值:

echo '<td><a class="index_table" href="includes/view.php?id=' . $row['id'] . '>' . $row['Orderno'] . '">';
                                                            ^^^^^^^^^^^^^^^^^^

请注意,您对SQL injection attacks 持开放态度,只是乞求获得您的服务器 pwn3d。

【讨论】:

    【解决方案2】:

    第一个问题:

    您必须将数组字符串索引放入括号中:

    echo '<td><a class="index_table" href="includes/view.php?id='.$row['id'].'">'.$row['Orderno'].'</a></td>';
                                                                ^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^
    

    第二个问题:

    您在 URL 中的 ID 很容易被 '; DELETE FROM table # 替换,从而允许攻击者执行 SQL 注入!始终清理参与 SQL 查询的任何用户输入 (POST) 或 GET 参数:

    $id = mysql_real_escape_string($_GET['id']);
    

    或者对于那种情况(当需要一个整数时)

    $id = (int) $_GET['id'];
    

    建议:不要使用 mysql_* 函数,而是使用 PDO 和(真实!)准备好的语句,或者至少使用 mysqli_* 函数并进行适当的输入清理。

    【讨论】:

      【解决方案3】:

      这里有两个大问题。首先,您的链接无法正常工作,因为您在回声中使用了单引号,这意味着变量没有被插值,因此您必须更改为以下任一内容:

      echo "<td><a class=\"index_table\" href=\"includes/view.php?id={$row['id']}>{$row['Orderno']}\">";
      

      echo '<td><a class="index_table" href="includes/view.php?id=' . $row['id'] . '>' . $row['Orderno'] . '">';
      

      警告 - 安全漏洞

      在您以后的代码中,您让自己容易受到 SQL 注入攻击;可以在OWASPWikipedia 找到有关此内容的一些参考资料,了解这些资料非常重要。为了保护自己,您必须在将数据发送到查询之前对其进行转义。以下是一些方法:

      $id = mysql_real_escape_string($_GET['id']); 
      $result=mysql_query("select * from Products where ID = '$id'");
      

      $id = $_GET['id']; 
      if (!ctype_digit((string)$id)) {
          die('Invalid ID: ' . htmlentities($id));
      }
      $result=mysql_query("select * from Products where ID = '$id'");
      

      在第一个示例中,我使用mysql_real_escape_string 使数据可以安全地嵌入到查询中(请注意,我还在变量周围添加了引号);第二,我做了一个数据检查以确保它只包含数字(注意长度也应该检查,但这是一个简单的例子),如果它包含数字以外的东西,我们会吐出一条错误消息并不要运行查询。

      【讨论】:

      • 你为什么要用手逃脱??? PHP 支持prepared statements,我没有理由想通过移交prepared statements 来逃避...
      • 提交者已经在使用旧的 mysql 驱动程序,我们不知道他/她的环境是什么样的,是否安装了 PDO,或者她/他必须进行哪些能力升级,如果有的话。在不完全改变范式的情况下以解决手头问题的方式回答要简单得多——如果我与提交者面对面交谈,我会在一秒钟内推荐 PDO,但这格式不太适合此类事情。
      【解决方案4】:

      更改您的查询,例如,我在 $id 之间添加了两个 '

      $result=mysql_query("select * from Products where ID='$id'");
      

      然后看看。

      【讨论】:

        【解决方案5】:

        您实际上并未在查询中包含 $id 变量的值。查看此答案以了解如何执行此操作的选项:

        How can I prevent SQL injection in PHP?

        PDO

        $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
        
        $stmt->execute(array(':name' => $name));
        
        foreach ($stmt as $row) {
            // do something with $row
        }
        

        mysqli

        $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
        $stmt->bind_param('s', $name);
        
        $stmt->execute();
        
        $result = $stmt->get_result();
        while ($row = $result->fetch_assoc()) {
            // do something with $row
        }
        

        【讨论】:

          【解决方案6】:

          您不应该像这样将GET 变量直接放入查询中,您应该进行一些完整性检查,例如检查它的数字等以避免sql注入。

          毫无疑问,您会得到答案说 mysql_ 函数也已被弃用,但我认为这与问题无关。

          在你的链接中

          <td><a class="index_table" href="includes/view.php?id=$row[id]>$row[Orderno]">
          

          你没有正确的数组元素语法,试试

          <td><a class="index_table" href="includes/view.php?id=' . $row['id'] . '>' . $row['Orderno'] . '">
          

          【讨论】:

            【解决方案7】:

            它看起来像是标签中的格式错误的 URL,而且 PHP 不解析单引号字符串中的变量。我想你只需要这个:

            echo "<td><a class='index_table' href='includes/view.php?id=$row[id]'>$row[Orderno]</a></td>";
            

            您不需要更改 view.php 中的代码,但我建议以这种方式过滤 _GET 变量:

            $id = (int)$_GET['id'];
            

            【讨论】:

              【解决方案8】:

              试试

              echo "<td><a class='index_table' href='includes/view.php?id=".$row['id'].">".$row['Orderno']."'>";
              

              <?php
              include 'connect.php';
              //Display the Data//
              $id=$_GET['id']; 
              if(is_int($id))
              {
                  $result=mysql_query("select * from Products where ID=$id");
                  $row=mysql_fetch_object($result);
                  echo "<table>";
                  echo "<tr bgcolor='#f1f1f1'><td><b>ID</b></td><td>$row->ID</td></tr>";
              }
              else
              {
                  echo "<h1>Nice try silly... You aint hackin me!</h1>";
              }
              

              我还注意到您在原始代码中缺少一些结尾引号和分号。那可能就是所有的错误。但这应该可以解决您的安全问题,并且应该适用于您的应用程序

              祝你好运。

              【讨论】:

                猜你喜欢
                • 2021-10-13
                • 2014-06-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-11-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多