CSRF(Cross Site Request Forgery) 跨站请求伪造,
Low
$_GET 变量:预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值。$_GET 变量是一个数组,内容是由 HTTP GET 方法发送的变量名称和值。可在url中直接设置
"UPDATE users SET password = '$pass_new' WHERE user = '" . $current_user . "';"$current_user变量直接插入到查询语句中。
Attack: /?password_new=1&password_conf=1&Change=1
Medium
stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false:检查 HTTP_REFERER 是否包含 SERVER_NAME。如果包含(即 stripos 返回的不是 false)
$_SERVER[ ‘HTTP_REFERER’ ]->referer
$_SERVER[ ‘SERVER_NAME’ ])->host
High 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 <?php $change = false ;$request_type = "html" ;$return_message = "Request Failed" ;if ($_SERVER ['REQUEST_METHOD' ] == "POST" && array_key_exists ("CONTENT_TYPE" , $_SERVER ) && $_SERVER ['CONTENT_TYPE' ] == "application/json" ) { $data = json_decode (file_get_contents ('php://input' ), true ); $request_type = "json" ; if (array_key_exists ("HTTP_USER_TOKEN" , $_SERVER ) && array_key_exists ("password_new" , $data ) && array_key_exists ("password_conf" , $data ) && array_key_exists ("Change" , $data )) { $token = $_SERVER ['HTTP_USER_TOKEN' ]; $pass_new = $data ["password_new" ]; $pass_conf = $data ["password_conf" ]; $change = true ; } } else { if (array_key_exists ("user_token" , $_REQUEST ) && array_key_exists ("password_new" , $_REQUEST ) && array_key_exists ("password_conf" , $_REQUEST ) && array_key_exists ("Change" , $_REQUEST )) { $token = $_REQUEST ["user_token" ]; $pass_new = $_REQUEST ["password_new" ]; $pass_conf = $_REQUEST ["password_conf" ]; $change = true ; } } if ($change ) { checkToken ( $token , $_SESSION [ 'session_token' ], 'index.php' ); if ( $pass_new == $pass_conf ) { $pass_new = mysqli_real_escape_string ($GLOBALS ["___mysqli_ston" ], $pass_new ); $pass_new = md5 ( $pass_new ); $current_user = dvwaCurrentUser (); $insert = "UPDATE `users` SET password = '" . $pass_new . "' WHERE user = '" . $current_user . "';" ; $result = mysqli_query ($GLOBALS ["___mysqli_ston" ], $insert ); $return_message = "Password Changed." ; } else { $return_message = "Passwords did not match." ; } mysqli_close ($GLOBALS ["___mysqli_ston" ]); if ($request_type == "json" ) { generateSessionToken (); header ("Content-Type: application/json" ); print json_encode (array ("Message" =>$return_message )); exit ; } else { echo "<pre>" . $return_message . "</pre>" ; } } generateSessionToken ();?>
添加功能:处理接受json信息;检验token(一次一换,随机生成)
array_key_exists ("CONTENT_TYPE", $_SERVER)
$_SERVER超级全局数组,包含关于头信息、路径和脚本位置的信息。
$_SERVER['CONTENT_TYPE'] == "application/json"传入请求的内容类型是否为JSON。
$data = json_decode(file_get_contents('php://input'), true);
使用file_get_contents('php://input')读取请求体中的原始POST数据,并将JSON数据解码为PHP数组。参数true表示结果数据应该是一个关联数组。
array_key_exists("user_token", $_REQUEST)
$_REQUEST数组包含来自$_GET、$_POST和$_COOKIE的数据。
header ("Content-Type: application/json");设置响应的内容类型为application/json。
`print json_encode (array(“Message” =>$return_message));``
$return_message变量编码为JSON格式的字符串并打印。
Impossible
add:验证旧密码
PDO::PARAM_STR:这是绑定参数的类型。在这里,它表示参数类型是字符串(PDO::PARAM_STR)。
其他
ftp与命令行了解 ftp> bye
SameSite
SameSite=None:允许Cookie在所有上下文中 发送,包括跨站请求。需要设置Secure属性。
SameSite=Lax:允许Cookie在顶级导航和第三方网站发起的GET请求时发送,在安全性和可用性之间取得平衡。
SameSite=Strict:Cookie只在同站 请求时发送
1 2 3 4 5 6 7 8 9 setcookie ("exampleCookie" , "value" , [ 'expires' => time () + 3600 , // 1 小时 'path' => '/' , 'domain' => 'example.com' , 'secure' => true , // 确保Cookie仅通过HTTPS发送 'httponly' => true , // Cookie仅通过HTTP协议访问 'samesite' => 'Strict' // 仅限同站请求发送Cookie ]);