Измените состояние БД через GET?

<�Сильный> 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 -->

<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
in your form:
<?php echo $fail ?> </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
"; return ""; } function validate_category_description($field) { if ($field == "") return "No description entered
"; 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() {

}

?>

Notice here that I get the user inputs thru POST then send that POST data to same .php file......then after validation send those data to another .php file THRU GET.....insert those GET data to the DB then after inserting those data we redirect to another page.

I read that if your changing the state of the database you should use POST not GET. My idea that it is bad because GET data can be seen in the URL so users can change the state of the database in the URL, another is when you click refresh if you use POST then the browser will warn you that your trying to repeat the same method again, BUT if you use GET the browser will not warn you so end up posting the same data twice.

In my code there is no way the user can manipulate the url to change the DB because as soon as the data is inserted we redirect to different page, and also the refresh problem is not a problem here.

I want to a place separated where I process my inputs and that is processCategory.php.

Im a noob please tell me if im dooing right.

1
добавлено
Просмотры: 1
de
«В моем коде пользователь не может манипулировать URL-адресом для изменения БД, потому что, как только данные будут вставлены, мы перенаправляемся на другую страницу», это очень опасная идея. Пользователь контролирует свой браузер, и они могут наблюдать за запросами, которые он делает. Ваш веб-сервер - это просто сервер в Интернете, который прослушивает HTTP-запросы на порт 80 и выплескивает ответы. Пользователи могут делать любые запросы, которые они хотят на веб-сервере, и сервер должен выполнять валидацию при каждом отдельном запросе, чтобы убедиться, что данные разумны.
добавлено автор Yuliy, источник
Остерегайтесь! HTTP GET-запросы должны быть «idempotent», то есть у них никогда не должно быть никаких побочных эффектов. Внесение изменений в данные является побочным эффектом. Вы должны only использовать POST для этого, а не GET.
добавлено автор Charles, источник
Я вижу благодарность за информацию
добавлено автор user1933652, источник
Но я хочу место для обработки моих данных, и это processCategory.php, и я хочу сначала проверить данные на одну и ту же страницу, прежде чем вставлять их в базу данных. Но я не могу перенаправить запрос на отправку.
добавлено автор user1933652, источник

1 ответы

Неважно, как туда попадают данные, он может быть изменен в режиме enroute. Вы можете поместить его в GET или POST, и пользователь может фальсифицировать его, сделать свой собственный запрос, или кто-то из них может его изменить (если вы не запустите https).

Ваш скрипт уязвим для SQL-инъекции в вашей функции addCategory. Вы должны изменить его как минимум:

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')";
...

Someone could put a part of an SQL query into any of those $_GET (or $_POST...it doesn't matter which) and possibly have it execute on your server. mysql_real_escape_string is a function provided for you so to make sure any parts of queries that may come in to your script by malicious users don't get through. Illustration here: http://xkcd.com/327/

Кроме того, вы можете искать с помощью PDO и параметризованных запросов, поскольку они еще более безопасны.

Что касается изменения пользователем и повторной отправки, вы можете предотвратить это с помощью Nonces. Nonce - это элемент безопасности, который является < n , используемым один раз . Самый простой способ сделать это может быть следующим: Когда вы показываете пользователю форму, вы должны поместить несколько видов в свою базу данных и затем поместить это число в скрытое поле в своей форме. Когда пользователь отправляет, сценарий видит в вашем поле nonce, проверяет, находится ли он в базе данных и удаляет его. Если скрипт не смог найти nonce, он знает, что его уже использовали, и поэтому он отклоняет запрос пользователя, поскольку этот запрос уже обработан. Чтобы дополнительно защитить это, поместите идентификатор пользователя в базу данных (при условии, что у вас есть какая-то обработка сеанса, которая дает идентификаторы пользователей) вместе с nonce, чтобы пользователь имел свой собственный nonce. Еще лучше было бы дать каждой сессии уникальный идентификатор и использовать его вместе с nonce. Хотя эта система не идеальна, она должна по крайней мере помочь в случае, когда пользователь случайно обновляет страницу. Вы можете подумать об этом как о «идентификаторе запроса», и как только «запрос id» был обработан, он не может быть обработан повторно.

Опять же, неважно, куда вы помещаете данные, пока вы его каким-то образом проверяете. Однако одно ограничение состоит в том, что некоторые браузеры (например, некоторые версии IE), как правило, не позволяют URL-адресам длиннее 2048 символов или около того. Данные POST обычно не так ограничены (кроме самого PHP), поэтому, если вы планируете отправлять много данных (например, сообщение на форуме), вы, вероятно, захотите использовать POST. Если вы отправляете очень мало данных (например, чириканье), вы можете использовать GET. Кроме того, пароли не должны отправляться через GET, так как браузер пользователя может сохранить это в своей истории, и вы не хотите, чтобы пароли всплывали повсюду в истории ...

РЕДАКТИРОВАНИЕ. В качестве побочной заметки вам необязательно иметь два отдельных URL-адреса для обработки ваших данных. Вы можете просто удалить любые части HTML из processCategory.php, использовать require processCategory.php в верхней части вашего addCategory.php, и вместо этой строки, где вы делаете заголовок перенаправления, замените его на что-то вроде:

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

Это не большое дело, но использование слишком большого количества перенаправлений и запросов может немного замедлить работу вашего сайта, а также заставить сервер получать больше запросов, чем нужно. Каждый раз, когда вы меняете заголовок Location, он отправляет 302, что делает браузер пользователя запрашивать у него другой URL-адрес.

1
добавлено
Когда вы делаете этот заголовок Location: вы на самом деле говорите браузеру пользователя, чтобы перейти на эту страницу. В этот момент кто-то может сказать своему браузеру приостановить и изменить URL-адрес, сделав его снова антисанитарным. Хорошее эмпирическое правило - никогда не доверять чему-либо, выходящему из $ _GET или $ _POST.
добавлено автор Los Frijoles, источник
Это все предпочтение и условность. Существует не установленное правило (но каждый будет спорить так или иначе). Мое личное предпочтение заключается в том, чтобы следовать так называемому соглашению RESTful: запросы GET получают вещи из базы данных, POST-запросы публикуют (добавлять) данные, PUT модифицируют и удаляют DELETE. Неважно, какое соглашение вы используете, просто пока вы понимаете, как он будет работать. Также имейте в виду, что только для запросов GET история браузера может кэшировать его, поэтому только помещайте туда вещи, которые вы не прочь увидеть в файле истории.
добавлено автор Los Frijoles, источник
Я думаю, что это немного грязно со всеми переадресациями (без обид), и я бы структурировал его по-другому, но это не значит, что мой путь - единственный способ. Если бы это был я, я бы использовал POST для изменения данных, поскольку это следует за соглашением RESTful. Использование GET не хуже (и некоторые места, которые отслеживают представления с использованием PHP, изменяют базу данных по запросам GET). Если вы хотите, чтобы ваш код больше соответствовал стандарту, посмотрите на использование механизма шаблонов (Savant3 - мой любимый) или рамки (CakePHP и Drupal являются популярными).
добавлено автор Los Frijoles, источник
Если данные попадают в ваш запрос, вы должны его дезинфицировать. Если он не попадает в запрос, на самом деле нет необходимости, если он не будет показан пользователю (посмотрите атаки на сценарии межсайтового сценария). Кроме того, выполнение таблицы DROP - это не единственное, что люди могут делать с SQL-инъекцией, и поэтому вы всегда предполагаете, что можете найти уязвимость в своем запросе или в самом PHP. Даже если mysql_query не может выполнить несколько запросов, кто скажет, что злоумышленник не может понять, как его обмануть.
добавлено автор Los Frijoles, источник
Он должен работать, потому что все, что он сделал бы, это избежать персонажа. Вы всегда можете попробовать и посмотреть.
добавлено автор Los Frijoles, источник
Я дезинфицирую вход пользователя сначала через fix_string (), а затем перенаправляю эти данные, если эти данные дезинфицируют, а затем зачем их санировать?
добавлено автор user1933652, источник
так что вы говорите, что можете манипулировать базой данных через $ _GET? bacause я читал, что если вы манипулируете данными, тогда вы должны использовать $ _POST. Мануализация базы данных означает вставку и удаление данных в базе данных.
добавлено автор user1933652, источник
Но у меня такое чувство, что мой код считается плохим кодом
добавлено автор user1933652, источник
если я следую за успокоительной конвенцией, я должен также дезинфицировать данные, поступающие из $ _GET ?? потому что данные не изменяли состояние в базе данных, поэтому зачем его дезинфицировать ???? mysql_query() и mysqli_query() могут выполнять только одно заявление sql, поэтому name '); Студенты DROP TABLE -? не работает.
добавлено автор user1933652, источник
если внутри базы данных есть «и если вы ищете», то вы санируете «вы получите»? извините im a noob
добавлено автор user1933652, источник