douchuanhan8384 2015-05-29 15:56
浏览 51
已采纳

关于INT的php分页安全性

I'm looking to update pagination on a page to PDO. However, I want to make sure it is 100% free from any SQL injection etc.

Below is the content of the pagination script I have found which I think will work without any issues. However as it will be pulling data from the URL I'm a bit concerned regarding the line:

if (isset($_GET["page"])) { $page  = $_GET["page"]; } else { $page=1; };

I can see isset is there to check if the variable is NULL (I think) but I can't see any checks for if it is not a number.

I was thinking of changing to:

if (isset($_GET["page"])) { $page  = (int)$_GET["page"]; } else { $page=1; };

As I think this will check if the page variable is a number. or should it be:

if (isset((int)$_GET["page"])) { $page  = $_GET["page"]; } else { $page=1; };

Or do I use INT on both? I think in old mysql you would have used striptags etc but not sure with PDO (still learning).

Here is the full code before the change mentioned above.

<?php
        include('connect.php');
        if (isset($_GET["page"])) { $page  = $_GET["page"]; } else { $page=1; };
        $start_from = ($page-1) * 3;        
        $result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT $start_from, 3");
        $result->execute();
        for($i=0; $row = $result->fetch(); $i++){
    ?>
    <tr class="record">
        <td><?php echo $row['a']; ?></td>
        <td><?php echo $row['b']; ?></td>
        <td><?php echo $row['c']; ?></td>
    </tr>
    <?php
        }
    ?>
</tbody>
</table>
<div id="pagination">
    <?php 

    $result = $db->prepare("SELECT COUNT(id) FROM members");
    $result->execute(); 
    $row = $result->fetch(); 
    $total_records = $row[0]; 
    $total_pages = ceil($total_records / 3); 

    for ($i=1; $i<=$total_pages; $i++) { 
                echo "<a href='index.php?page=".$i."'";
                if($page==$i)
                {
                echo "id=active";
                }
                echo ">";
                echo "".$i."</a> "; 
    }; 
    ?>

Connect.php contains

$db = new PDO('mysql:host='.$db_host.';dbname='.$db_database, $db_user, $db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Any help or guidance would be greatly appreciated. Also if you can spot anything else security wise, please let me know.

EDITS:

Added line:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

to connect.php

Any other security tips?

  • 写回答

1条回答 默认 最新

  • dthdlv9777 2015-05-29 15:59
    关注

    Use parameterized queries this will avoid the possibility of injections. To do that using PDO you can

    1. Pass the user provided values into the execute in an array
    2. Place a question mark as a placeholder in place of the user data
    $result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT ?, 3");
    $result->execute(array((int)$start_from));
    

    You also can bind it, http://php.net/manual/en/pdostatement.bindparam.php (based on doc and other threads, I don't usually bind).

    $result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT :start, 3");
    $result->bindParam(':start', (int)$start_from, PDO::PARAM_INT);
    $result->execute();
    

    Here's a longer thread on it, How can I prevent SQL injection in PHP?

    Also PHP notes on it, http://php.net/manual/en/pdo.prepared-statements.php

    For a longer sample, if you had multiple values coming in:

    $result = $db->prepare("SELECT * FROM members where username = ? and email = ? ORDER BY id ASC LIMIT ?, 3");
    $result->execute(array($_GET['name'], $_GET['email'], $start_from));
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi