Facebook 身份验证示例 CSRF

发布于 2024-12-03 19:11:19 字数 2025 浏览 3 评论 0原文

Facebook 身份验证示例位于 http://developers.facebook.com/docs/authentication/尝试通过将随机分组的信息插入到 auth_request 的 status 部分来防止 CSRF。当 auth_request 返回时,代码会进行检查以确保请求返回了相同的随机组。这对 CSRF 有何影响?

代码:

<?php 

   $app_id = "YOUR_APP_ID";
   $app_secret = "YOUR_APP_SECRET";
   $my_url = "YOUR_URL";

   session_start();
   $code = $_REQUEST["code"];

   if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

   if($_REQUEST['state'] == $_SESSION['state']) {
     $token_url = "https://graph.facebook.com/oauth/access_token?"
       . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
       . "&client_secret=" . $app_secret . "&code=" . $code;

     $response = file_get_contents($token_url);
     $params = null;
     parse_str($response, $params);

     $graph_url = "https://graph.facebook.com/me?access_token=" 
       . $params['access_token'];

     $user = json_decode(file_get_contents($graph_url));
     echo("Hello " . $user->name);
   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }

 ?>

信息位添加到此处的请求中:

 if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

并在此处进行检查:

 if($_REQUEST['state'] == $_SESSION['state'])

如何确保它们具有相同的“状态”以确保没有 CSRF?

谢谢

The Facebook authentication example given at http://developers.facebook.com/docs/authentication/ tries to prevent CSRF by inserting a random grouping of information into the status part of the auth_request. When that auth_request returns, the code checks to make sure that same random group has been returned with the request. How does that precent CSRF?

The code:

<?php 

   $app_id = "YOUR_APP_ID";
   $app_secret = "YOUR_APP_SECRET";
   $my_url = "YOUR_URL";

   session_start();
   $code = $_REQUEST["code"];

   if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

   if($_REQUEST['state'] == $_SESSION['state']) {
     $token_url = "https://graph.facebook.com/oauth/access_token?"
       . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
       . "&client_secret=" . $app_secret . "&code=" . $code;

     $response = file_get_contents($token_url);
     $params = null;
     parse_str($response, $params);

     $graph_url = "https://graph.facebook.com/me?access_token=" 
       . $params['access_token'];

     $user = json_decode(file_get_contents($graph_url));
     echo("Hello " . $user->name);
   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }

 ?>

The bit of information is added to the request here:

 if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

And checked here:

 if($_REQUEST['state'] == $_SESSION['state'])

How does ensuring they have the same "state" ensure no CSRF?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

围归者 2024-12-10 19:11:19

哈希(或状态)由您为 Web 服务 (Facebook) 的每个请求生成,并存储在服务器上的会话中。该哈希值随您网站的请求一起发送至 Facebook。 Facebook 将完全相同的哈希值作为响应参数发送回来。

您要做的就是检查请求之前生成的哈希值是否与响应中的哈希值匹配。

   MyWebsite   |    Facebook
---------------+-----------------
               |
Generate $hash |
  Store $hash  |
               |
             $hash
    ----------------------->
               |
             $hash
    <-----------------------
               |
  Check $hash  |

这可以防止 CSRF,因为每个请求的哈希值都不同。显然,如果您对每个请求使用相同的字符串,那么任何知道(或猜测)它的人都可以伪造响应。

请求完成后,检查会话中的哈希值和响应中的哈希值是否匹配。如果它们不匹配,则很可能是伪造的响应。检查后,从会话中清除该值,因为您将不再需要它。

在一般情况下(不仅仅是 Facebook 的实现),存储哈希的超时通常是明智的。这将防止稍后使用/利用不完整请求的哈希值。没有适合所有应用程序和案例的单一时间,但在像这样的次要请求/操作的情况下,30 秒到 1 分钟就可以了。

The hash (or state) is generated by you for each request to the web service (Facebook) and stored in the session on your server. This hash is sent with the request to Facebook from your website. Facebook sends the exact same hash back as a parameter on the response.

All you do is check if the hash generated before the request matches the one in the response.

   MyWebsite   |    Facebook
---------------+-----------------
               |
Generate $hash |
  Store $hash  |
               |
             $hash
    ----------------------->
               |
             $hash
    <-----------------------
               |
  Check $hash  |

This prevents CSRF because the hash is different for each request. Obviously, if you use the same string for each request, anyone who knows (or guesses) it will be able to forge a response.

Once the request is complete, check the hash from the session and the hash in the response both match. If they don't match, it's likely to be a forged response. After you check, clear the value from the session as you won't be needing it again.

In general cases (not just Facebook's implementation), it's often wise to also store a timeout for the hash. This will prevent a hash from an incomplete request being used/exploited at a later date. There is no single time that will fit all applications and cases, but in the case of a secondary request/action like this, 30s-1 minute would do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文