PHP 和 JavaScript 变量传递和安全性

Posted

技术标签:

【中文标题】PHP 和 JavaScript 变量传递和安全性【英文标题】:PHP and JavaScript variable passing and security 【发布时间】:2018-12-31 05:45:23 【问题描述】:

我正在尝试为我的论文评论网站制作一个通知系统,这是应该发生的基本流程:

这是我的表结构(mysql):

我遇到的问题是,一旦用户接受或拒绝审核请求,我无法弄清楚如何安全地更新关系表中的状态。我可以将接受/拒绝按钮的值设置为关系的 id 并使用 ajax 来更新该关系的状态,但这似乎并不安全,因为用户可以使用检查元素更改值。

这是我所拥有的示例: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_relation 的状态列,当用户单击通知的接受或拒绝按钮时,通知表示该状态列。

问题是我无法找到一种方法来将关系 id(或描述关系的 reviewer_id 和essay_id)与其通知相关联,而不将其直接放入通知的 html 中,因为它很容易被更改。

我不经常提问,因此非常感谢您对问题的标题、书写或陈述方式提出任何批评。如果需要任何其他信息,请询问。谢谢!

【问题讨论】:

我们总是乐于帮助和支持新的编码员,但您需要先帮助自己。 :-)doing more research 之后,如果您有问题发布您尝试过的方法,并清楚地解释什么不起作用并提供a Minimal, Complete, and Verifiable example。阅读How to Ask 一个好问题。请务必take the tour 并阅读this。 @JayBlanchard 感谢您的建议!我已阅读材料并更新了问题。很抱歉,它在“我尝试过的”方面缺乏,但我能想到和查找的所有内容都无法满足我所需要的要求。 基本上,您应该让 AJAX API 通过会话或令牌检查用户的身份。如果您的 API 调用解析器中有用户身份,它应该能够确定用户是否可以或不能以特定方式更改事物。简而言之,您会知道用户是否有权访问该文章,并且您会知道用户是否可以将状态设置为启用/禁用。 如果您担心黑客可能会嗅探令牌/会话,请在您的服务器上使用 HTTPS。 Let's Encrypt 可免费使用。 谢谢考拉,我的问题不是试图查看用户是否有编辑权限,而是当只有该通知的 html 可用于sql语句。我想我有一个解决方案。稍后我会发布它作为答案。 【参考方案1】:

我相信我已经找到了解决方案: 我在用户文章关系表中添加了一个令牌列,以便可以使用唯一的、加密安全的令牌标识每个请求(有关令牌生成代码,请参阅 Scott 的更新答案 here)。 然后,当通知插入到通知表中时,我将接受按钮的值设置为令牌。这样,当加载通知页面时,可以使用.val() 检索令牌,并与 ajax 一起使用来更新相应请求的状态。因此,虽然用户可以更改按钮的值,但他们猜测另一个请求的 100 个字符长的令牌的机会非常小。 如果这不像我想象的那么安全,请告诉我。

【讨论】:

以上是关于PHP 和 JavaScript 变量传递和安全性的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量和数据从 PHP 传递到 JavaScript?

如何使用 Javascript 和 Ajax 将 HTML 单选按钮值传递给 PHP 变量?

使用 Ajax 在 Javascript 文件中传递和使用 PHP 变量

将变量从 WordPress PHP 传递到 JavaScript

将变量从 PHP 传递到 javascript 并传递到 html 表单

将 JavaScript 变量传递给 PHP,然后传递给 woo commerce 支持的电子商务网站中的购物车和订单项