web安全代码基础-PHP(身份验证技术)

📅 2026/6/29 19:54:08
web安全代码基础-PHP(身份验证技术)
身份验证技术基本概念1、Cookie存储位置客户端浏览器文本文件特点数据保存在用户本地每次请求自动携带发给服务器大小限制约 4KB不安全用户可篡改、删除无过期设置则浏览器关闭自动销毁可设置有效期持久保存适合存储非敏感数据记住用户名、浏览记录2、Session存储位置服务器端文件 / Redis / 数据库特点仅在客户端存一个唯一PHPSESSIDCookie真正数据在服务端安全用户无法直接修改会话数据浏览器关闭默认 Session 失效可手动销毁适合敏感数据登录状态、用户 ID、权限两者的原理过程1、生成cookie的原理过程1、客户端向服务器发送HTTP请求。2、服务器检查请求头中是否包含cookie信息。3、如果请求头中包含cookie信息则服务器使用该cookie来识别客户端否则服务器将生成一个新的cookie。4、服务器在响应头中设置cookie信息并将其发送回客户端。5、客户端接收响应并将cookie保存在本地。6、当客户端发送下一次HTTP请求时它会将cookie信息附加到请求头中。7、服务器收到请求并检查cookie的有效性。8、如果cookie有效则服务器响应请求。否则服务器可能会要求客户端重新登录。2、生成session的原理过程1、客户端向服务器发送HTTP请求。2、服务器为客户端生成一个唯一的sessionID并将其存储在服务器端的存储器中如文件、数据库等。3、服务器将生成的sessionID作为一个cookie发送给客户端。4、客户端将sessionID保存为一个cookie通常是在本地浏览器中存储。5、当客户端在发送下一次HTTP请求时它会将该cookie信息附加到请求头中以便服务器可以通过该sessionID来识别客户端。6、服务器使用sessionID来检索存储在服务器端存储器中的与该客户端相关的session数据从而在客户端和服务器之间共享数据。两者的代码示例1、PHP Cookie 完整示例?php // 1. 设置Cookiesetcookie() 必须在任何输出前执行不能有echo、html空格 // 参数名称, 值, 过期时间, 路径, 域名, https, httponly // 示例1关闭浏览器就失效的cookie setcookie(username, zhangsan); // 示例2有效期1小时当前时间3600秒 $expire time() 3600; setcookie(user_token, abc123xyz, $expire); // 示例3全站生效、仅https、禁止js读取防XSS setcookie(safe_cookie, data123, $expire, /, , true, true); // 2. 读取Cookie超全局 $_COOKIE echo 读取Cookiebr; if(isset($_COOKIE[username])){ echo 用户名 . $_COOKIE[username] . br; } if(isset($_COOKIE[user_token])){ echo 令牌 . $_COOKIE[user_token] . br; } // 3. 删除Cookie设置过期时间为过去时间 setcookie(username, , time() - 3600); echo 已删除username Cookie; ?2、PHP Session 完整示例?php // 第一步开启会话必须放在代码最顶部无任何输出 session_start(); // 1. 写入Session服务端存储 $_SESSION[user_id] 1001; $_SESSION[nickname] 小王; $_SESSION[is_login] true; // 2. 读取Session echo Session数据 br; if(isset($_SESSION[is_login]) $_SESSION[is_login]){ echo 用户ID . $_SESSION[user_id] . br; echo 昵称 . $_SESSION[nickname] . br; echo 登录状态已登录br; } // 查看浏览器自动生成的Session CookiePHPSESSID echo br当前会话ID . session_id(); // 3. 删除单个Session变量 unset($_SESSION[nickname]); // 4. 清空全部Session数据 session_unset(); // 5. 彻底销毁会话清除服务端文件 客户端PHPSESSID cookie session_destroy(); // 清除本地保存的session id cookie setcookie(session_name(), , time()-3600, /); ?3、结合登录实战案例//login.php ?php session_start(); // 模拟账号密码 $user [ name admin, pwd 123456 ]; if($_POST){ $name $_POST[name]; $pwd $_POST[pwd]; if($name $user[name] $pwd $user[pwd]){ // 登录成功Session存登录状态服务端安全 $_SESSION[login_user] $name; $_SESSION[login_time] time(); // Cookie记住用户名前端持久下次自动填充 setcookie(remember_name, $name, time()86400*7); // 7天 header(Location: index.php); exit; }else{ $msg 账号密码错误; } } ? !DOCTYPE html form methodpost 用户名input namename value?php echo $_COOKIE[remember_name]?? ?br 密码input typepassword namepwdbr button typesubmit登录/button ?php echo $msg?? ? /form//index.php验证登录 ?php session_start(); // 判断Session是否存在登录标识 if(!isset($_SESSION[login_user])){ header(Location: login.php); exit; } $user $_SESSION[login_user]; echo 欢迎你{$user}已登录; echo bra hreflogout.php退出登录/a; ?//lodinout.php退出销毁会话 ?php session_start(); // 清空session session_unset(); session_destroy(); // 删除记住用户名的cookie setcookie(remember_name, , time()-1, /); header(Location: login.php); exit; ?两者存在的安全问题1、Cookie脆弱问题Cookie 存在两大安全短板未设置HttpOnlyJS 可直接读取 CookieXSS 攻击偷凭证;Cookie 存储在客户端用户可手动修改内容伪造身份演示XSS 窃取 Cookie脆弱点 1//后端 setcookie 未加 HttpOnly危险写法 ?php // 危险没有第七个参数httponlytrueJS能读取cookie setcookie(user_token, admin_token_123, time()3600, /); ? !-- 存在XSS漏洞页面 -- div 用户留言?php echo $_GET[msg]; ? /div !-- 攻击者传入URL?msgscriptalert(document.cookie)/script -- script // 直接读出 Cookie拿到登录凭证 console.log(document.cookie); /script修复方案开启 HttpOnlyJS 无法读取:// 第七个参数 true HttpOnly阻断JS读取Cookie setcookie(user_token, admin_token_123, time()3600, /, , false, true);演示客户端篡改 Cookie脆弱点 2//服务端错误逻辑直接信任 Cookie 中的身份不做服务端校验 ?php // 危险逻辑以Cookie里的role判断管理员 setcookie(role, user, time()3600, /); // 业务校验 if ($_COOKIE[role] admin) { echo 欢迎超级管理员可以删除所有数据; } else { echo 普通用户无删除权限; } ? //攻击过程用户打开浏览器开发者工具 → 应用 / Cookie手动把 role 值从 user 改成 admin刷新页面直接获得管理员权限。核心根源修复方案根源Cookie 在客户端可自由修改不能存可信权限、身份数据。2、Session固定问题Session 固定攻击者提前给用户植入一个已知的PHPSESSID用户登录后服务器仍沿用这个会话 ID攻击者使用同一个 SESSIONID 即可劫持用户登录会话。漏洞成因登录前后不重新生成 session_id。演示Session 固定攻击//login.php危险代码未 regenerate_id ?php session_start(); // 攻击者提前通过链接植入会话IDxxx.com/login.php?PHPSESSIDhack123456 $name $_POST[name] ?? ; $pwd $_POST[pwd] ?? ; // 账号密码正确直接写入session不更换会话ID if ($name admin $pwd 123456) { $_SESSION[is_login] true; $_SESSION[username] admin; header(Location: index.php); exit; } ? form methodpost 用户名:input namename 密码:input typepassword namepwd button登录/button /form//index.php ?php session_start(); if (!$_SESSION[is_login]) { exit(未登录); } echo 管理员后台可操作敏感数据;攻击流程攻击者构造链接http://xxx.com/login.php?PHPSESSIDhack123456发给受害者受害者点开链接浏览器 Cookie 被写入PHPSESSIDhack123456此时有两者情况1、未登录时直接就行下一步2、已经登录时URL 传的 PHPSESSID 优先级 Cookie 里的 PHPSESSID但是此时需要受害者重新登录才能绑定危险Session受害者输入账号密码登录服务器没有换新 session_id继续使用hack123456攻击者在自己浏览器设置相同PHPSESSIDhack123456访问 index.php直接窃取登录会话修复方案登录成功后强制重新生成会话 ID//修改 login.php 登录成功分支添加 session_regenerate_id(true) ?php session_start(); $name $_POST[name] ?? ; $pwd $_POST[pwd] ?? ; if ($name admin $pwd 123456) { // 关键防御生成全新session_id删除旧会话文件抵御Session固定 session_regenerate_id(true); $_SESSION[is_login] true; $_SESSION[username] admin; header(Location: index.php); exit; } ?session_regenerate_id(true)作用创建全新随机会话 IDtrue参数同步删除服务器上旧的 Session 文件 攻击者提前植入的旧 SESSIONID 彻底失效无法劫持会话。参考链接Cookie脆弱问题【代码审计】xhcms-脆弱鉴权逻辑-CSDN博客Session固定问题【代码审计】yxcms从伪XSS到Getshell-先知社区补充TokenTokenToken 翻译令牌、凭证是服务端发给客户端的一串加密 / 唯一字符串用来证明身份替代传统 CookieSession 做登录鉴权。最主要的一点。Token适用于前后端分离状态下的鉴权如APP、小程序等工作流程用户提交账号密码到服务端服务端校验账号正确后把用户ID、用户名、过期时间等信息加密生成 Token返回 Token 给前端浏览器 / APP / 小程序前端把 Token 存在 localStorage / Cookie之后每次接口请求请求头带上 TokenAuthorization: Bearer xxx服务器接收请求解密 / 校验 Token合法放行接口识别当前登录用户过期 / 篡改返回 401 未授权跳登录页Token和Session的核心区别和Cookie区别比较明显就是Cookie是“容器”。主要是和Session的区别Session客户端传 ID服务端查表拿用户数据Token客户端传打包好、带防伪签名的完整身份信息服务端验签即用不用查表。服务器压力变小Cookie就是存Session的ID和Token的完整身份信息的“容器”。