dongliuzhuan1219 2016-07-22 08:11
浏览 11
已采纳

使用session禁用来自网站外部的帖子请求(php安全性)

i want disable post request that sent from another url or software (CSRF attacks) and notice that : ( i don't want set csrf token input for my forms )

is accepted if i set csrf token in session after users login ? thanks

  • 写回答

1条回答 默认 最新

  • dongsang6899 2016-07-22 08:46
    关注

    If you want to avoid CRSF, you don't have any good options. The $_SERVER['HTTP_REFERER'] variable is often set and usually corresponds to the website the request came from, so you could use it to block some foreign requests. However like all data coming from the browser, you cannot trust it without verification so it should not be considered secure. The docs say:

    This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

    CSRF checking is the best option to prevent foreign domains from making requests. You don't have to include it as an input on your forms if you don't want to; you can use cookies and headers instead:

    1. When the user logs in, use PHP's setcookie to store a token in cookies. Store a matching token in the user session, along with an expiration date

    $token = '...'; //<- look up how to generate a good random token
    $expire = time()+1800; //expire in 30 minutes
    setcookie("XSRF-TOKEN", $token, $expire);  /* expire in 1 hour */
    $_SESSION['XSRF-TOKEN'] = ['token'=>$token, 'exp'=>$expire];
    

    2. When your site makes a request, use Javascript to read the token from document.cookie and set the header below with the exact same value:

    X-XSRF-TOKEN: 43b7acd76d6....
    

    If you're worried about having to update a big website, this is your best bet. You can instruct the browser to run a Javascript function whenever it's about to make an HTTP request. This function could read the cookie and set the header. Many frameworks will do this for you, but for vanilla JS, look at this resource.

    3. Whenever your PHP script receives a request, first look for the value of this header, then compare it to what you saved in the user session. Remember to check for expiration!

    $request_token = apache_request_headers()['X-XSRF-TOKEN']? : null;
    $session_token = $_SESSION['XSRF-TOKEN'];
    if($request_token===null) die('Token is missing');
    if($session_token['exp'] < time()) die('Token has expired');
    if($session_token['token']!==$request_token) die('Token is invalid');
    //safe to continue. Repeat step 1 to set a fresh token
    

    Only the domain that can read the XSRF-TOKEN cookie will know what value to set in the header. Since browsers do not allow one domain to read cookies from another, this mechanism will protect you from requests of bad origin. And it keeps the csrf bits out of your forms as you asked.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Matlab在app上输入带有矩阵形式的初始条件发生错误
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题
  • ¥15 用ADS设计一款的射频功率放大器