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。
我是一个菜鸟请告诉我,如果我正确的话。
答案 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。