对匿名用户使用 CSRF 保护是否有意义?

Does it make sense to use CSRF protection for anonymous users?

是否应该为匿名用户使用 CSRF 保护,或者这是否违背了它的目的?

我有一个可以匿名访问的URL。当使用适当的信息访问 URL 时,我的数据库中的一些值会更新。例如,客户可以在他们的订单确认页面上放置一些代码,这些代码将向 http://example.com/save-request 发出 POST 请求,并发送以下数据:

{orderId: 1234, referralCode: 'ABCDEF'}

当我收到此请求时,我使用推荐代码更新数据库中的给定订单:

$order = Order::find(Input::get('orderId'));
$order->referral_code = Input::get('referralCode');
$order->save();

我正在努力保护此 URL 免受滥用,以便用户无法发送随机订单 ID 的请求并尝试获取与其相关联的推荐代码。

想到了 CRSF 保护,但这意味着我需要先获取令牌,这将需要另一个 public URL。这似乎会使滥用变得稍微困难​​一些,但仍然有可能,因为滥用者可以简单地获取令牌,然后像往常一样发出请求。

是否有任何策略可以防止此类滥用行为?

CSRF 旨在保护经过身份验证的 会话。基本思想是:服务器为所有经过身份验证的会话向客户端提供一个 CSRF 令牌。客户端应该在每个后续请求中将相同的 CSRF 令牌传递给服务器。因此,如果请求没有令牌,服务器应该忽略/记录它。理想情况下,您的 CSRF 令牌应该仅在身份验证 时传递给客户端 。如果有一个单独的 URL 来获取 CRSF 令牌,它就变得毫无意义。

在您的情况下,由于用户在 "order confirmation" 始终是匿名的,因此 CSRF 保护不太适用。我认为最好的策略是对数据和您的 API 建模,这样每个 "order confirmation" 都是一个带有可选 "referralCode" 的原子请求。然后,您的 API function/endpoint,可能 /confirm-order,可以将 referralCode 与任何其他确认处理逻辑一起保存到 Order 对象中。 API function/endpoint 编辑命令,也许 /edit-order,应该需要身份验证。然后,应用标准的 CSRF 保护。

但是,如果您打算允许 匿名 用户更改他们的订单详细信息,包括 referralCode,您可以通过跟踪更改来减少滥用,并且只允许最多变化的数量。如果有帮助,您还可以添加一些时间限制。

我同意 CSRF 令牌对未经身份验证的请求没有用,但它也没有害处并且不会增加额外的工作(在 Laravel 的情况下),因此在大多数情况下没有真正的理由可以省略它到处都是。

关于您的问题的解决方案,请尝试将订单的 id 替换为生成的随机 order_number 之类的东西,这比简单的 id 更难猜测。

另一个解决方案是这样的:

$order = Order::where('id', '=', Input::get('orderId'))
    ->where('created_at', '=', Input::get('createdAt'))->first();

if ($order) {
    $order->referral_code = Input::get('referralCode');
    $order->save();
}

在这种情况下,用户必须猜测 id 并猜测特定订单的创建时间。

您也可以混合使用两种解决方案(order_numbercreated_at)。

这不是 100% 完美的解决方案,但大大降低了欺诈的可能性。

祝你好运!