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

时间:2015-06-30 16:20:01

标签: php laravel csrf

CSRF保护是否应该用于匿名用户,或者这是否会破坏其目的?

我有一个可以匿名访问的网址。使用适当的信息访问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();

我正在尝试保护此网址免遭滥用,以便用户无法发送随机订单ID请求,并尝试将其推介代码与其相关联。

我想到了CRSF保护,但这意味着我需要首先获取令牌,这需要另一个公共URL。这似乎会使滥用稍微困难,但仍然可能,因为滥用者可以简单地获取一个令牌,然后正常发出请求。

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

2 个答案:

答案 0 :(得分:2)

我同意CSRF令牌对于未经身份验证的请求没有用,但它也没有任何损害,也没有额外的工作(如果是Laravel),所以在大多数情况下没有真正的理由在这里和那里省略它。 / p>

如何解决您的问题,请尝试使用生成的随机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%解决方案,但会大大降低欺诈的可能性。

祝你好运!

答案 1 :(得分:1)

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

在您的情况下,由于用户在“订单确认”中始终是匿名的,因此CSRF保护不会太适用。我认为最好的策略是对数据和API建模,使每个“订单确认”是一个带有可选“referralCode”的原子请求。然后,您的API函数/端点(可能是/confirm-order)可以使用referralCode并将其与任何其他确认处理逻辑一起保存到Order对象中。用于编辑订单的API函数/端点(可能是/edit-order)应该要求身份验证。然后,标准的CSRF保护适用。

但是,如果您打算允许匿名用户更改其订单详细信息(包括referralCode),则可以通过跟踪更改来缓解滥用行为,并且只允许最大数量的更改。如果它有帮助,您也可以添加一些时间限制。