通过GET改变DB的状态?

时间:2012-12-28 04:49:56

标签: php

addCategory.php

<?php
$parentId = isset($_GET['parentId']) ? $_GET['parentId'] : 0;

$categoryName = $categoryDescription = "";
$fail = "";


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

    if (isset($_POST['categoryName']))
        $categoryName = fix_string($_POST['categoryName']);

    if (isset($_POST['categoryDescription']))
        $categoryDescription = fix_string($_POST['categoryDescription']);

    $hidParentId = $_POST['hidParentId'];
}

$fail  = validate_category_name($categoryName);
$fail .= validate_category_description($categoryDescription);


echo "<html><head><title>An Example Form</title>";

if ($fail == "") {
  echo "success";

    header("Location: processCategory.php?action=add&categoryName=$categoryName&categoryDescription=$categoryDescription&hidparentId=$hidParentId");

    exit;
}

// Now output the HTML and JavaScript code
?>

<!-- The HTML section -->

<style>.signup { border: 1px solid #999999;
    font: normal 14px helvetica; color:#444444; }</style>
<script type="text/javascript">
function validate(form)
{

    fail  = validateCategoryName(form.categoryName.value)
    fail += validateCategoryDescription(form.categoryDescription.value)

    if (fail == "") return true
    else { alert(fail); return false }
}
</script></head><body>
<table class="signup" border="0" cellpadding="2"
    cellspacing="5" bgcolor="#eeeeee">
<th colspan="2" align="center">Add Category</th>

<?php

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

<tr><td colspan="2">Sorry, the following errors were found<br />
in your form: <p><font color=red size=1><i><?php echo $fail ?></i></font></p>
</td></tr>

<?php 
}
?>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?parentId=<?php echo $parentId; ?>"
    onSubmit="return validate(this)">
     <tr><td>Category Name</td><td><input type="text" maxlength="32"
    name="categoryName" value="<?php echo $categoryName; ?>" /></td>
    </tr><tr><td>Category Description</td><td><input type="text" maxlength="32"
    name="categoryDescription" value="<?php echo $categoryDescription; ?>" /></td>

    <input type="hidden" name="hidparentId" value="<?php echo $parentId; ?>" />

</tr><tr><td colspan="2" align="center">
    <input type="submit" name="submit" value="ok" /></td>
</tr></form></table>

<!-- The JavaScript section -->

<script type="text/javascript">
function validateCategoryName(field) {
    if (field == "") return "No name entered.\n"
    return ""
}

function validateCategoryDescription(field) {
    if (field == "") return "No description entered.\n"
    return ""
}

</script></body></html>

<?php
// Finally, here are the PHP functions

function validate_category_name($field) {
    if ($field == "") return "No name entered<br />";
    return "";
}

function validate_category_description($field) {
    if ($field == "") return "No description entered<br />";
    return "";
}

function fix_string($string) {
    if (get_magic_quotes_gpc()) $string = stripslashes($string);
    return htmlentities ($string);
}

?>



processCategory.php

<?php
$action = isset($_GET['action']) ? $_GET['action'] : '';
switch ($action) {

    case 'add' :
        addCategory();
        break;

    case 'modify' :
        modifyCategory();
        break;

    case 'delete' :
        deleteCategory();
        break;

    default :
        // if action is not defined or unknown
        // move to main category page
        header('Location: index.php');
}


/*
    Add a category
*/
function addCategory() {



    $name        = $_GET['categoryName'];
    $description = $_GET['categoryDescription'];
    $parentId  = $_GET['hidparentId'];

    $sql   =  "INSERT INTO tbl_category (cat_parent_id, cat_name, cat_description) 
            VALUES ($parentId, '$name', '$description')";
    $result = dbQuery($sql) or die('Cannot add category' . mysql_error());

    header('Location: index.php?catId=' . $parentId);     

}

function modifyCategory() {

}

function deleteCategory() {

}

?>

请注意,我通过POST获取用户输入,然后将POST数据发送到相同的.php文件......然后在验证后将这些数据发送到另一个.php文件THRU GET .....将那些GET数据插入到数据库然后在插入这些数据后,我们重定向到另一个页面。

我读过如果你改变数据库的状态,你应该使用POST而不是GET。我认为它很糟糕,因为可以在URL中看到GET数据,因此用户可以更改URL中数据库的状态,另一种是当您使用POST时单击刷新,然后浏览器会警告您尝试重复同样的方法,但如果您使用GET,浏览器将不会警告您,因此最终会发布两次相同的数据。

在我的代码中,用户无法操纵URL来更改数据库,因为只要插入数据,我们就会重定向到不同的页面,而且刷新问题也不是问题。

我希望在处理输入的地方分开一个地方,即processCategory.php。

我是一个菜鸟请告诉我,如果我正确的话。

1 个答案:

答案 0 :(得分:1)

数据如何到达并不重要,可以通过途径进行修改。您可以将其置于GET或POST中,用户可以伪造它,发出自己的请求,或者中间某人可以修改它(除非您运行https)。

您的脚本容易受到addCategory函数中的SQL注入攻击。你应该尽可能地修改它:

function addCategory() {
    $name        = mysql_real_escape_string($_GET['categoryName']);
    $description = mysql_real_escape_string($_GET['categoryDescription']);
    $parentId  = mysql_real_escape_string($_GET['hidparentId']);

    $sql   =  "INSERT INTO tbl_category (cat_parent_id, cat_name, cat_description) 
            VALUES ($parentId, '$name', '$description')";
...

有人可以将SQL查询的一部分放入任何$ _GET(或$ _POST ......无关紧要),并可能在服务器上执行。 mysql_real_escape_string是为您提供的功能,以确保恶意用户可能进入您脚本的查询的任何部分都无法通过。插图:http://xkcd.com/327/

此外,您可能希望使用PDO和参数化查询进行查找,因为这些更安全。

对于用户修改内容和重新提交,您可以通过使用Nonce来防止这种情况。 nonce是一个安全的东西,它是“ n 使用一次”。执行此操作的一种非常简单的方法可能如下:当您向用户显示表单时,您应该在数据库中添加一些类型,然后将该数字放入表单上的隐藏字段中。当用户提交时,脚本会在您的字段中查看nonce,检查它是否在数据库中,然后将其删除。如果脚本找不到nonce,它知道它已被使用,因此它拒绝用户的请求,因为该请求已被处理。为了进一步确保这一点,请将用户的id放在数据库中(假设您有某种会话处理,它提供用户ID)以及nonce,以便用户拥有自己的nonce。更好的方法是给每个会话一个唯一的id,并将其与nonce一起使用。虽然这个系统并不完美,但至少应该在用户意外刷新页面的情况下提供帮助。您可以将其视为“请求ID”,一旦处理了“请求ID”,就无法再次处理它。

同样,只要您以某种方式验证数据,放置数据的位置无关紧要。然而,一个限制是某些浏览器(如某些版本的IE)倾向于不允许超过2048个字符左右的URL。 POST数据通常不会受到限制(除了PHP本身),因此如果您计划发送大量数据(如论坛上的帖子),您可能希望使用POST。如果您发送的数据非常少(如推文),您可以使用GET。此外,密码不应该通过GET发送,因为用户的浏览器可能会在其历史记录中保留密码,并且您不希望密码在历史记录中随处可见......

编辑:作为旁注,您不一定要有两个单独的URL来处理您的数据。您可以从processCategory.php中删除任何HTML部分,使用addCategory.php顶部的require processCategory.php,而不是执行重定向标题的行,将其替换为:

addCategory();
header("Location: someSuccessPage.php");

这不是什么大问题,但是使用过多的重定向和请求可能会使您的网站速度降低一些,并且还会导致您的服务器接受的请求超出其需求。每次更改Location标头时,它都会发出一个302,使用户的浏览器从服务器请求另一个URL。