GET请求里放修改操作会被CSRF攻击吗?

Zz超霞 阅读 19

我最近在做用户设置页面,不小心把“删除草稿”功能写成了GET请求,类似点个链接就删了。后来听说这样会有CSRF风险,但我不太确定是不是真的有问题?

比如下面这种写法:

<a href="/api/delete-draft?id=123" rel="external nofollow" >删除草稿</a>
<!-- 后端用PHP接收$_GET['id']然后直接删库 -->

我已经改成POST了,但想搞明白:为什么GET不能用来做数据修改?浏览器或服务器层面会自动防这种攻击吗?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
志鸽
志鸽 Lv1
你说的情况确实存在CSRF(跨站请求伪造)的风险。GET请求通常用于获取数据,而不应该用来执行修改操作,比如删除数据。这是因为GET请求可以通过多种方式被触发,比如点击链接、加载图片、甚至是通过其他网站的iframe等,这给了攻击者一个利用的机会。

在你的例子中,如果攻击者诱导用户访问一个包含恶意链接的页面,用户的浏览器会在不知情的情况下发送一个GET请求到你的服务器,从而删除指定的草稿。这就是典型的CSRF攻击。

改成POST请求是个好的改进,因为POST请求不会被浏览器自动发送,需要用户明确的交互,比如点击提交按钮。但这还不够,为了进一步防止CSRF攻击,你还需要在每个表单中添加一个唯一的CSRF令牌,并在服务器端验证这个令牌。

这里有个简单的PHP示例来说明如何生成和验证CSRF令牌:

session_start();

// 生成CSRF令牌
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// 显示表单,包含CSRF令牌
echo '




';

// 验证CSRF令牌
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('Invalid CSRF token');
}
// 处理删除逻辑
$draftId = $_POST['id'];
// 这里要记得防止SQL注入,最好使用预处理语句
$stmt = $pdo->prepare('DELETE FROM drafts WHERE id = :id');
$stmt->execute(['id' => $draftId]);
}


这样做可以有效防止CSRF攻击,同时记得对用户输入的数据进行适当的验证和清理,防止SQL注入等其他安全问题。虽然现代浏览器有一些内置的安全机制来防止CSRF,但我们不能完全依赖它们,还是需要自己实现一些防御措施。
点赞
2026-03-23 17:00