CVE-2021-3776: Cross-Site Request Forgery (CSRF) (CWE-352)
value: showdoc is vulnerable to Cross-Site Request Forgery (CSRF)
CWE description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
CVSS v3 base score: 5.4
Published: 2021-11-13T10:15Z
Repository: https://github.com/star7th/showdoc
Language: PHP
Files changed: server/Application/Api/Controller/UserController.class.php
Commit date: 2021-10-19 22:19:10 +0800
Commit message: Strict cookie

Diff: diff --git a/server/Application/Api/Controller/UserController.class.php b/server/Application/Api/Controller/UserController.class.php
index f72f6539..92ef92b1 100644
--- a/server/Application/Api/Controller/UserController.class.php
+++ b/server/Application/Api/Controller/UserController.class.php
@@ -40,12 +40,16 @@ class UserController extends BaseController {
                     //设置自动登录
                     $ret = D("User")->where("uid = '$new_uid' ")->find() ;
                     unset($ret['password']);
                     session("login_user" , $ret );
                     $token = D("UserToken")->createToken($ret['uid']);
-                    cookie('cookie_token',$token,array('expire'=>60*60*24*90,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
-                  $this->sendResult(array(
+                    if(version_compare(PHP_VERSION,'7.3.0','>')){
+                        setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
+                      }else{
+                        cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
+                    }
+                    $this->sendResult(array(
                     "uid" => $ret['uid'] ,
                     "username" => $ret['username'] ,
                     "name" => $ret['name'] ,
                     "groupid" => $ret['groupid'] ,
                     "avatar" => $ret['avatar'] ,
@@ -132,11 +136,15 @@ class UserController extends BaseController {
             }
           unset($ret['password']);
           session("login_user" , $ret );
           D("User")->setLastTime($ret['uid']);
           $token = D("UserToken")->createToken($ret['uid'],60*60*24*180);
-          cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
+          if(version_compare(PHP_VERSION,'7.3.0','>')){
+            setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
+          }else{
+            cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
+          }
           $this->sendResult(array(
             "uid" => $ret['uid'] ,
             "username" => $ret['username'] ,
             "name" => $ret['name'] ,
             "groupid" => $ret['groupid'] ,
@@ -245,12 +253,15 @@ class UserController extends BaseController {
                     //设置自动登录
                     $ret = D("User")->where("uid = '$new_uid' ")->find() ;
                     unset($ret['password']);
                     session("login_user" , $ret );
                     $token = D("UserToken")->createToken($ret['uid']);
-                    cookie('cookie_token',$token,array('expire'=>60*60*24*90,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
-                    
+                    if(version_compare(PHP_VERSION,'7.3.0','>')){
+                        setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
+                      }else{
+                        cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
+                    }                    
                     $this->sendResult(array(
                         "uid" => $ret['uid'] ,
                         "username" => $ret['username'] ,
                         "name" => $ret['name'] ,
                         "groupid" => $ret['groupid'] ,

Vulnerable code:                     cookie('cookie_token',$token,array('expire'=>60*60*24*90,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
                  $this->sendResult(array(
          cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
                    cookie('cookie_token',$token,array('expire'=>60*60*24*90,'httponly'=>'httponly'));//此处由服务端控制token是否过期，所以cookies过期时间设置多久都无所谓
                    
Fixed code:                     if(version_compare(PHP_VERSION,'7.3.0','>')){
                        setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
                      }else{
                        cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
                    }
                    $this->sendResult(array(
          if(version_compare(PHP_VERSION,'7.3.0','>')){
            setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
          }else{
            cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
          }
                    if(version_compare(PHP_VERSION,'7.3.0','>')){
                        setcookie('cookie_token',$token,array('expires'=>time()+60*60*24*180,'httponly'=>'httponly','samesite' => 'Strict','path'=>'/'));
                      }else{
                        cookie('cookie_token',$token,array('expire'=>60*60*24*180,'httponly'=>'httponly'));
                    }