HTTP_REFERER行为 - 需要帮助

时间:2013-04-16 02:24:49

标签: php mysql

我有三个单独的页面:modify.php允许用户选择发布者并为该发布者创建会话变量。

modify.php

<?php
    session_start();
    require ("../login.php");

    if (!isset($_SESSION['user']))
        header('Location: ../index.php');

    if (isset($_POST['submit'])) {
        $_SESSION['publisher'] = $_POST['publishers'];
        header('Location: modify2.php');
    }

    $user_id = $_SESSION['user'];
    $success = true;

    include ("header.php");
    include ("subnav.php");

    $stmt = $db->prepare
        ("SELECT DISTINCT p.name 
        FROM subscriptions s
        JOIN titles t
            ON s.title = t.id
        JOIN publishers p
            ON t.publisher = p.name
        WHERE s.user=:user
        ORDER by p.name");
    $stmt->bindValue(':user', $user_id, PDO::PARAM_INT);
    $stmt->execute();
    $rows = $stmt->fetchAll();
    $num_rows = count($rows);
    if ($num_rows == 0) {
        $success = false;
        $errors[] = 'You currently have no subscriptions.';
    }
?>

    <h2>Modify Subscriptions</h2>

    <?php
        if (!empty($errors))
            foreach($errors as $error)
                echo $error;
    ?>

<?php
        if ($success == true) { ?>
            <form action="" method="post">
                <ul>
                    <li>
                        Select Publisher:<br>
                        <select name="publishers">
                        <?php
                        foreach($rows as $row) {
                            echo '<option value ="'. $row['name'] . '">' . $row['name'] . '</option>';  
                        }   ?>
                        </select>
                    </li>
                    <li>
                        <input type="submit" value="Select Publisher" name ="submit" id="submit">
                    </li>
                </ul>
            </form>
<?php   } ?>

<?php   
    include ("footer.php");
?>

modify2.php从modify.php接收会话变量“publisher”,并检索该发布者的标题。然后它取消设置发布者会话变量有两个原因:1)不再需要它2)如果此变量为空,则mofify2.php知道引用来自错误的页面

modify2.php

<?php
    session_start();
    require ("../login.php");

    if (!isset($_SESSION['user']))
        header('Location: ../index.php');

    if (!isset($_SESSION['publisher']))
        header('Location: modify.php');

    $referer = $_SERVER['HTTP_REFERER'];
    if (basename($referer) <> 'modify.php')
        header('Location: modify.php');

    if (isset($_POST['submit'])) {
        $_SESSION['title'] = $_POST['title'];
        unset($_SESSION['publisher']);
        header('Location: modify3.php');
    }

    $user_id = $_SESSION['user'];
    $publisher = $_SESSION['publisher'];

    include ("header.php");
    include ("subnav.php");

    $stmt = $db->prepare
        ("SELECT t.title
        FROM titles t
        JOIN publishers p
            ON t.publisher = p.name
        JOIN subscriptions s
            ON t.id = s.title
        WHERE s.user=:user AND t.publisher=:publisher
        ORDER by t.title");
    $stmt->bindValue(':user', $user_id, PDO::PARAM_INT);
    $stmt->bindValue(':publisher', $publisher, PDO::PARAM_STR);
    $stmt->execute();
    $rows = $stmt->fetchAll();
    $num_rows = count($rows);
    if ($num_rows == 0)
        $errors[] = 'There are currently no titles for that publisher.';
?>

    <h2>Modify Subscriptions</h2>

    <?php
        if (!empty($errors))
            foreach($errors as $error)
                echo $error;
    ?>

    <form action="" method="post">
        <ul>
            <li>
                Select Title:<br>
                <select name="title">
                <?php
                foreach($rows as $row) {
                    echo '<option value ="'. $row['id'] . '">' . $row['title'] . '</option>';  
                }   ?>
                </select>
            </li>
            <li>
                <input type="submit" value="Select Title" name ="submit" id="submit">
            </li>
        </ul>
    </form>

<?php   
    include ("footer.php");
?>

这个文件是问题所在。无论出于何种原因,我的http_referer代码块都会阻止访问该页面。任何帮助将不胜感激。

modify3.php

<?php
    session_start();
    require ("../login.php");

    if (!isset($_SESSION['user']))
        header('Location: ../index.php');

    if (!isset($_SESSION['title']))
        header('Location: modify2.php');

    $referer = $_SERVER['HTTP_REFERER'];
    if (basename($referer) <> 'modify2.php');
        header('Location: modify2.php');

    $user_id = $_SESSION['user'];
    $title = $_SESSION['title'];
    $success = false;

    if (isset($_POST['submit'])) {

        $covers = (isset($_POST['covers'])) ? 1 : 0;

        if (empty($_POST['quantity']))
            $errors[] = 'You must enter a quantity!';
        else if (!is_numeric($_POST['quantity']))   
            $errors[] = 'You must enter a number for the quantity field!';
        else if (is_numeric($_POST['quantity']) && $_POST['quantity'] > 5)
            $errors[] = 'If you want to subscribe to more than 5 of the same issue, please contact us';
        else {
            $stmt = $db->prepare("UPDATE subscriptions SET quantity=:quantity, covers=:covers WHERE user=:id AND title=:title");
            $stmt->bindValue(':quantity', $_POST['quantity'], PDO::PARAM_INT);
            $stmt->bindValue(':covers', $covers, PDO::PARAM_INT);
            $stmt->bindValue(':id', $user_id, PDO::PARAM_INT);
            $stmt->bindValue(':title', $title, PDO::PARAM_INT);
            $stmt->execute();
            $success = true;
            unset($_SESSION['title']);
        }
    }

    include ("header.php");
    include ("subnav.php");

?>

    <h2>Modify Subscriptions</h2>

    <?php
        if (!empty($errors))
            foreach($errors as $error)
                echo $error;
    ?>

    <?php 
        if ($success == false) { ?>
            <form action="" method="post">
                <ul>
                    <li>
                        <b>Title To Modify:</b><br>
                        <?php 
                        $stmt = $db->prepare("SELECT title FROM titles WHERE id=:title");
                        $stmt->bindValue(':title', $title, PDO::PARAM_STR);
                        $stmt->execute();$rows = $stmt->fetchAll(); 
                        foreach ($rows as $row) {
                            echo $row['title'];
                        }
                        ?>
                    </li>
                    <li>
                        <br><input type="checkbox" name="covers" value="covers"
                        <?php
                            $stmt = $db->prepare("SELECT covers FROM subscriptions WHERE user=:id AND title=:title");
                            $stmt->bindValue(':id', $user_id, PDO::PARAM_INT);
                            $stmt->bindValue(':title', $title, PDO::PARAM_INT);
                            $stmt->execute();
                            $rows = $stmt->fetchAll();
                            foreach ($rows as $row)
                                if ($row['covers'] == 1)
                                    echo 'checked';
                        ?>
                        >Check to opt-in for all regular priced covers.
                    </li>
                    <li>
                        <br><b>Quantity Requested:</b> <br>
                        <input type="text" name="quantity" value="<?php $stmt = $db->prepare("SELECT quantity FROM subscriptions WHERE user=:user AND title=:title"); $stmt->bindValue(':user', $user_id, PDO::PARAM_INT); $stmt->bindValue(':title', $title, PDO::PARAM_INT); $stmt->execute(); $rows = $stmt->fetchAll(); foreach ($rows as $row) echo $row['quantity']; ?>">
                    </li>
                    <li>
                        <input type="submit" value="Save Changes" name="submit" id="submit">
                    </li>
                </ul>
            </form>
<?php   } 
        else { ?>
            <p>You have succesfully updated your title!</p>
<?php   }   ?>


<?php   
    include ("footer.php");
?>

如果我拿出以下代码块:

$referer = $_SERVER['HTTP_REFERER'];
        if (basename($referer) <> 'modify2.php');
            header('Location: modify2.php');

然后我的页面正常工作,但它不会阻止人们手动将其输入浏览器并以错误的方式访问它。

1 个答案:

答案 0 :(得分:3)

您不能依赖浏览器发送的Referer标头。事实上,其中一些提供了出于“安全”原因欺骗它的选项。

相反,您应该在$_SESSION数组中保存一个变量,指示用户是否以正确的方式访问了该页面。