You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止篡改URL中GET传递的ID以非法读取其他用户数据库数据?

防止URL ID篡改读取他人数据的解决方案

核心思路:绑定数据归属 + 双重校验

不管用哪种方法,核心都是确保只有数据的所有者才能访问对应的数据,以下是具体可落地的方案:

1. Session结合用户身份校验(最稳妥的基础方案)

如果你的系统有用户登录体系,直接通过Session关联用户与数据:

  • 第一步:给存储表单数据的数据库表新增user_id字段,关联用户表的主键(用户注册/登录后,Session中会存储$_SESSION['user_id'])。
  • 第二步:用户提交表单并验证通过后,插入数据时同步写入当前用户的user_id:
// 示例用PDO操作数据库
$stmt = $pdo->prepare("INSERT INTO form_data (content, user_id) VALUES (?, ?)");
$stmt->execute([$validatedContent, $_SESSION['user_id']]);
$insertedId = $pdo->lastInsertId();
  • 第三步:汇总页查询时,除了URL传递的id,必须加上user_id的过滤条件,同时用预处理语句防范SQL注入:
$targetId = $_GET['id'];
$stmt = $pdo->prepare("SELECT * FROM form_data WHERE id = ? AND user_id = ?");
$stmt->execute([$targetId, $_SESSION['user_id']]);
$data = $stmt->fetch();

// 若查询无结果,说明用户无权访问,直接跳转或提示
if (!$data) {
    echo "<script>alert('无权访问该数据'); window.location.href='index.php';</script>";
    exit;
}

这样就算有人篡改URL里的id,数据库也只会返回当前用户自己的数据,无法读取他人内容。

2. 加密URL中的ID(额外防护层)

如果担心明文ID暴露数据量或被枚举,可将ID加密后再放到URL中,服务器端解密后再查询:

  • 提交后重定向时加密ID:
$plainId = $insertedId;
$secretKey = "你的服务器专属密钥(需保密,不能存前端)";
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encryptedId = openssl_encrypt($plainId, 'aes-256-cbc', $secretKey, 0, $iv);

// 将加密后的ID和IV一同传给前端(IV可公开)
$redirectUrl = "summary.php?id=" . urlencode($encryptedId) . "&iv=" . urlencode(base64_encode($iv));
echo "<script>window.location.href='$redirectUrl';</script>";
  • 汇总页解密并查询:
$secretKey = "与加密时一致的密钥";
$encryptedId = urldecode($_GET['id']);
$iv = base64_decode(urldecode($_GET['iv']));
$plainId = openssl_decrypt($encryptedId, 'aes-256-cbc', $secretKey, 0, $iv);

// 依然要结合user_id校验,实现双重保险
$stmt = $pdo->prepare("SELECT * FROM form_data WHERE id = ? AND user_id = ?");
$stmt->execute([$plainId, $_SESSION['user_id']]);
$data = $stmt->fetch();

3. 用随机Token替代ID(无用户体系时的方案)

如果项目没有用户登录功能(比如匿名提交场景),可以用随机生成的Token标识数据:

  • 提交表单时生成并存储Token:
// 生成16位随机Token
$token = bin2hex(random_bytes(16));
$stmt = $pdo->prepare("INSERT INTO form_data (content, token) VALUES (?, ?)");
$stmt->execute([$validatedContent, $token]);
  • 重定向到带Token的汇总页:
echo "<script>window.location.href='summary.php?token=$token';</script>";
  • 汇总页通过Token查询:
$token = $_GET['token'];
$stmt = $pdo->prepare("SELECT * FROM form_data WHERE token = ?");
$stmt->execute([$token]);
$data = $stmt->fetch();

由于Token是随机生成的,他人很难猜到有效Token,从而避免篡改访问。

注意事项

  • 无论采用哪种方案,必须使用预处理语句(PDO/mysqli prepare),防范SQL注入是基础安全要求。
  • Session需做好安全配置:开启session.cookie_httponly防止XSS窃取Session,开启session.cookie_secure(若使用HTTPS)。

内容的提问来源于stack exchange,提问作者H3ry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:05:28