Быстрый, простой и безопасный способ выполнения действий с БД с помощью GET - PullRequest
1 голос
/ 12 апреля 2010

Вопрос о методах / передовых методах, который, я уверен, был решен, но я не могу найти решение, основанное на нечетких поисковых терминах, которые я ввожу.

Я знаю, что если начать с вопроса "Быстро и легко", то, вероятно, несколько вздохну, поэтому мои извинения.

Вот сделка.

У меня есть авторизованная область, где ADMIN может выполнять целый ряд операций POST для ввода данных, относящихся к их профилю. То, как я структурировал данные, довольно отчетливо и хорошо сегментировано в большинстве таблиц, так как относится к ID администратора.

Теперь у меня есть таблица, в которую я добавляю данные одного типа и различаю эти данные, назначая уникальный идентификатор ADMIN для каждой записи. Другими словами, все ADMIN имеют этот тип записи данных в эту таблицу. Я просто различаю по идентификатору ADMIN для каждой записи.

Я планировал , чтобы позволить ADMIN удалить эти записи, щелкнув ссылку со строкой запроса - очевидно, с помощью GET. Очевидно, что структура запроса находится в ссылке, поэтому любой вошедший в систему администратор может затем использовать URL-адрес и удалить записи конкурента.

Это единственный способ безопасно сделать это через POST или я должен пройти через информацию о сеансе, которая содержит пароль, и проверить его по ID ADMIN, который запрашивает удаление?

Это, очевидно, намного больше работы для меня.

Как они сказали в авторемонтном бизнесе, в котором я работал ... Есть 3 способа сделать работу: быстро, хорошо и дешево. Вы можете иметь только два одновременно. Быстро и дешево не будет хорошо. У хорошего и дешевого не будет быстрого оборота. Быстро и хорошо НЕ будет дешево. ха-ха

Я думаю, что это применимо здесь ... никогда не может быть быстрым, легким и безопасным одновременно;)

Заранее спасибо ...

Ответы [ 3 ]

3 голосов
/ 12 апреля 2010

Как правило, любая операция, которая изменяет состояние (будь то состояние сеанса или состояние базы данных), должна использовать POST. Это означает, что единственной «безопасной» операцией SQL, которую вы можете выполнить с помощью GET, является SELECT. Даже если вы используете только административную часть, вы не должны использовать get. Представьте, что вы снова открываете свой браузер и обнаруживаете, что в последний раз, когда вы закрывали Firefox, вы находились на странице «УДАЛИТЬ ВСЕ» GET-> delete, в результате чего все снова удалялось.

Одной из основных причин этого является предотвращение подделки межсайтовых запросов. Например, если у вас была страница с переменной GET, такой как http://example.com/account?action=logout,, злоумышленник может опубликовать изображение на вашем сайте следующим образом:

<img src="http://example.com/account?action=logout" />

и любой, кто откроет страницу, содержащую этот тег изображения, будет немедленно отключен, даже если он был администратором. Было бы очень неприятно искать эти данные в вашей необработанной базе данных и удалять их.

Хотя POST-операции «почти» легко подделать, как правило, при решении любой проблемы веб-безопасности компромисс - скорость / простота в сравнении с безопасностью, поэтому вам придется выбирать одну или другую. .

2 голосов
/ 12 апреля 2010

У вас должна быть настроена какая-то сессия.

Использование POST поверх GET ничего не дает в плане безопасности. ПОЧТЫ могут быть подделаны так же, как GET.

Итак, если ваш администратор войдет в систему, вы получите какой-то идентификатор в сеансе, вы просто используете его.

Рассмотрим что-то похожее на это:

<?PHP
session_start();

if (empty ($_SESSION['admin_id'])) die("Log in, son.");

if (empty($_GET['record_id'])) die("You've got to tell me which record to delete!");

if (! is_numeric($_GET['record_id'])) die("Invalid record ID");

//just to be totally safe, even though we just enforced that it's numeric.
$record_id = mysql_real_escape_string($_GET['record_id']));

$sql = "DELETE FROM table WHERE record_id='{$record_id}' AND admin_id = {$_SESSION['admin_id']}";

mysql_query($sql);

echo "Record was deleted (assuming it was yours in the first place)";
?>

В этом примере мы избегаем проблемы «удалить чужие записи», используя предложение WHERE в запросе DELETE. Конечно, чтобы быть более удобным для пользователя, вам нужно сначала получить запись, затем сравнить admin_id в записи с admin_id в $ _SESSION, и если они не совпадают, жаловаться, регистрировать что-либо, выдавать ошибку и т.д.

НТН

0 голосов
/ 12 апреля 2010

Вы говорите: «Что, если Администратор 123 получит доступ к URL-адресу Администратора 321 напрямую, удалив его содержимое?» нет?

Если это так, то каждый зарегистрированный администратор должен иметь хотя бы один сеанс с уникальным идентификатором для этого администратора. Если нет, то он не должен быть в первую очередь в разделе администратора. Разве вы не можете просто сравнить идентификатор в URL с идентификатором в сеансе?

Если какой-либо пользователь, а не только администратор, получит доступ к этим URL-адресам "удалите меня", он должен быть идентифицирован в сеансе как первоначальный "владелец" (администратор) этих данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...