PHP и JavaScript передача переменных и безопасность

Я пытаюсь создать систему уведомлений для моего сайта рецензирования эссе, вот основной поток того, что должно произойти:

течь

и вот структуры моих таблиц (MySQL):

схема

У меня проблема в том, что я не могу понять, как безопасно обновить статус в таблице отношений после того, как пользователь принимает или отклоняет запрос на проверку. Я мог бы установить значения кнопок принятия / отклонения для идентификатора отношения и использовать ajax для обновления статуса этого отношения, но это не кажется безопасным, поскольку пользователь может просто изменить значение с помощью элемента inspect.

Вот пример того, что у меня есть:
request.php

<?php
//define global variables
$dbhost = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbdatabase = "test";
$conn = new mysqli($dbhost, $dbusername, $dbpassword, $dbdatabase);
?>
<a href="user43notifs.php">Click here to go to user 43's notifications</a><br><br>

<!--Example requests-->

<form action="request.inc.php" method="post">
  op_id: 43<br>
  reviewer_id: 42<br>
  essay_id: 34<br>
  <input type="hidden" name="op_id" value="43">
  <input type="hidden" name="reviewer_id" value="42">
  <input type="hidden" name="essay_id" value="34">
  <input type="submit" name="submit">
</form>
<form action="request.inc.php" method="post">
  op_id: 43<br>
  reviewer_id: 16<br>
  essay_id: 135<br>
  <input type="hidden" name="op_id" value="43">
  <input type="hidden" name="reviewer_id" value="16">
  <input type="hidden" name="essay_id" value="135">
  <input type="submit" name="submit">
</form>
<form action="request.inc.php" method="post">
  op_id: 78<br>
  reviewer_id: 12<br>
  essay_id: 25<br>
  <input type="hidden" name="op_id" value="78">
  <input type="hidden" name="reviewer_id" value="12">
  <input type="hidden" name="essay_id" value="25">
  <input type="submit" name="submit">
</form>

request.inc.php

<?php
//define global variables
$dbhost = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbdatabase = "test";
$conn = new mysqli($dbhost, $dbusername, $dbpassword, $dbdatabase);

$op = mysqli_real_escape_string($conn, $_POST['op_id']);
$reviewer = mysqli_real_escape_string($conn, $_POST['reviewer_id']);
$essay = mysqli_real_escape_string($conn, $_POST['essay_id']);

$sql = "INSERT INTO `reviewer_relations` (`reviewer_id`, `essay_id`, `status`)
VALUES ('$reviewer', '$essay', 0)";

$result=mysqli_query($conn, $sql);
if($result === TRUE){
  $title = mysqli_real_escape_string($conn, $reviewer." has requested to review your essay: essay#".$essay.".");
  $message = mysqli_real_escape_string($conn, '<button onclick="location.href=\'scripts/review_request.php?confirmation=accept\'" class="review-accept">Accept</button><button onclick="location.href=\'scripts/review_request.php?confirmation=decline\'" class="review-decline">Decline</button>');
  $sql = "INSERT INTO `notifications` (`user_id`, `title`, `message`)
  VALUES ('$op', '$title', '$message')";

  $result=mysqli_query($conn, $sql);

  if($result === TRUE){
    echo 'notification and relation insert success';
  }
  else{
    echo 'notification insert fail: '.mysqli_error($conn);
  }
}
else{
  echo 'relation insert fail: '.mysqli_error($conn);
}
?>

user43notifs.php

<?php
$dbhost = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbdatabase = "test";
$conn = new mysqli($dbhost, $dbusername, $dbpassword, $dbdatabase);

$sql="SELECT *
FROM notifications
WHERE user_id = 43";
$result = mysqli_query($conn, $sql);
while($row = mysqli_fetch_assoc($result)){
  echo '**********************************************<br>';
  echo $row['title'].'<br>';
  echo $row['message'].'<br>';
}
?>

используя эти две таблицы таблиц, настроенных с помощью PHPMyAdmin:
reviewer_relations
reviewer_relations
уведомления

Мне нужен безопасный способ обновить столбец состояния для reviewer_relation, который представлен уведомлением, когда пользователь нажимает на кнопку подтверждения или отклонения указанного уведомления.

Проблема в том, что я не могу найти способ связать идентификатор отношения (или reviewer_id и essay_id, которые описывают отношение) с его уведомлением, не помещая его непосредственно в HTML-код уведомления, где он уязвим для изменения.

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

1 ответ

Решение

Я считаю, что нашел решение:
Я добавил столбец токена в таблицу отношений пользователя и эссе, чтобы каждый запрос можно было идентифицировать с помощью уникального криптографически безопасного токена (см. Обновленный ответ Скотта здесь для кода, генерирующего токен).
Затем, когда уведомление вставляется в таблицу уведомлений, я устанавливаю значение кнопки "Принять" в качестве токена. Таким образом, при загрузке страницы уведомлений токен можно получить с помощью .val() и используется с ajax для обновления статуса соответствующего запроса. Таким образом, хотя пользователь может изменить значение кнопки, шансы угадать токен длиной в 100 символов другого запроса астрономически невелики.
Пожалуйста, дайте мне знать, если это не так безопасно, как я думаю.

Другие вопросы по тегам