ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Web网页绕过登录:Cookie/JWT登录态注入与鉴权旁路

Web网页绕过登录:Cookie/JWT登录态注入与鉴权旁路 做 web 开发或者做安全测试的朋友大概率都遇到过这么个场景手头一个后台系统每天要点开登录页、输账号、收验证码、再点登录一整套流程走下来十几秒就没了要是赶上做自动化回归测试脚本跑到登录页就卡住整个用例链路直接断掉。所以web 网页绕过登录这个词在实际工程里出现的频率比想象中高得多。我先把话说在前头这篇内容只讨论三种合法场景——你自己开发维护的系统、明确授权的测试靶场、以及安全夺旗赛的练习环境。对任何不是你自己的、没有书面授权的系统动手都属于越界这部分内容我一个字都不会涉及也建议你不要去试。接下来我会把我在实际项目里用过的两种方式拆开讲透包括它们各自的原理、适用边界、具体操作步骤以及踩过的坑。1. 先搞清楚绕过登录在工程里到底指什么1.1 两种方式的分界线在哪里很多人一听到绕过登录脑子里第一反应是去猜密码、爆破、注入。但在真实工程语境下这个词 90% 的情况指的是合法地复用或构造一个已有的登录态而不是去破解别人的账号。我把它归纳成两大类这两类的技术路径完全不同适用场景也完全不同。方式一从客户端侧接管登录态。核心思路是服务端的认证逻辑我一点都不改我只是把浏览器里那份我已经登录过的凭据拿到手然后注进去。具体表现就是 Cookie 注入、LocalStorage 注入、请求头注入。这种方式对服务端零侵入改完随时能撤最大的优势是安全、可回溯出了问题一清空存储就回到原状。方式二从服务端侧做鉴权放行。核心思路反过来客户端我不动我在服务端的鉴权链路上开一个只对特定环境生效的旁路比如测试环境专用开关、mock 的令牌签发器、或者网关层的白名单。这种方式能做到彻底不用登录适合自动化流水线跑集成测试但它对代码有侵入性开关配错了就是生产事故。两条路的本质区别在于你信任谁。方式一是我拿到了真实凭据所以服务端认我方式二是我让服务端在特定条件下不认凭据。想清楚这个区别后面的选型就不会乱。1.2 选型前必须先确认的三件事动手之前我会先确认三件事这三件事没确认清楚后面写多少代码都是白费。第一认证凭据存在哪。现代 web 应用的登录态大致分三派传统 Session 派把 sessionId 放在 Cookie 里前后端分离派把 JWT 放在 LocalStorage 或 SessionStorage 里还有混合派refresh token 放 HttpOnly Cookieaccess token 放内存变量。你要先打开开发者工具把 Application 面板里的 Storage 全翻一遍再看 Network 面板里每个请求带了什么头才能知道该往哪里注入。第二服务端的校验点在哪。是网关统一校验还是每个微服务各校验一次是中间件拦截还是注解式鉴权这个决定了方式二能不能做、好不好做。第三环境标识怎么区分。这是方式二的生命线。Spring 的Profile、Node 的NODE_ENV、K8s 的命名空间、配置中心的独立配置集你得有一个可靠的、不可能在生产生效的隔离机制。我在实际项目里见过因为配置文件复制粘贴导致测试开关进生产的案例后果非常严重所以这一条我从来不妥协。提示方式二的所有改动都必须加上环境不匹配时直接抛异常的硬保护而不是环境匹配时才生效的软判断。前者错了会报错后者错了会静默放行。1.3 两种方式的适用场景对照为了让你快速定位自己属于哪种情况我整理了一张对照表。这张表是我按实际项目经验总结的不是理论推演。维度方式一客户端接管登录态方式二服务端鉴权放行服务端改动零改动需要新增代码或配置适用环境任意环境的自己账号仅测试/预发环境典型用途前端联调、UI 自动化、手动提效集成测试流水线、压测、演示环境凭据时效跟随真实凭据的有效期由旁路逻辑自己控制风险等级低随时可撤销高配置错误影响面大实现成本半小时到半天一到三天取决于架构推荐优先级优先考虑方式一确实做不到时再用说实话我自己的习惯是能用方式一解决的绝不碰方式二。因为方式一的成本低、风险小、可回滚而且它复用真实凭据测试结果的可信度反而更高。方式二是在方式一撞到墙的时候才拿出来的备选。2. 方式一客户端侧接管登录态的完整实操2.1 第一步把认证凭据的位置摸清楚打开你要处理的页面先正常登录一次然后按 F12 打开开发者工具。这时候你要做的是三看。看 Cookie。切到 Application 面板的 Cookies 项把当前域名下的所有 Cookie 列出来。重点看几个特征名字里带session、token、sid、jsessionid、auth的基本就是目标看HttpOnly列打了勾的说明 JavaScript 读不到只能通过请求头自动携带看Expires列会话级的 Cookie 关浏览器就没了看SameSite列这决定了跨站请求能不能带上它。看 Storage。同一个面板里的 Local Storage 和 Session Storage 逐个域名翻。前后端分离的项目token 十有八九就躺在 Local Storage 里key 名可能是token、access_token、Authorization、user_info之类。有时候它是被 JSON 序列化后塞进去的比如存的是{token:xxx,expire:1735660800000}这种情况你注入的时候要把整个 JSON 结构对齐。看请求头。切到 Network 面板刷新页面找一个需要登录才能访问的接口比如/api/user/info点开看它的 Request Headers。认证信息一定在这里出现要么是Cookie: JSESSIONIDxxx要么是Authorization: Bearer eyJhbGci...要么是自定义头比如X-Token、X-Auth-Token。这三看做完你就拿到了完整的注入图纸往哪存、存什么名字、什么格式、带在哪个头上。注意有些系统做了双令牌设计access token 有效期 15 分钟refresh token 有效期 7 天。你注入的时候两个都得带上只带 access token 的话脚本跑到第 16 分钟就全线崩了。这种坑我在做长链路自动化测试时踩过排查了大半天才发现是令牌过期。2.2 第二步手工注入并验证图纸有了接下来是最直接的一步——手工注入。我在浏览器控制台里通常这么干// 注入 LocalStorage 形式的令牌 localStorage.setItem(token, eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx.yyy); localStorage.setItem(token_type, Bearer); // 如果系统存的是 JSON 结构则要按原结构写入 localStorage.setItem(user_info, JSON.stringify({ token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx.yyy, userId: 10086, role: tester })); // 注入完刷新页面看是否直接进入已登录状态 location.reload();如果是 Cookie 形式的会稍微麻烦一点因为HttpOnly的 Cookie 用document.cookie是写不进去的。这时候有三个办法一是直接在 Application 面板里双击 Cookie 的值手动改二是在控制台用 Chrome DevTools Protocol 的方式写比较绕不推荐三是干脆别改 Cookie改用请求头注入因为大多数服务端框架在读取令牌时请求头的优先级是高于 Cookie 的。再补充一个我常用的办法Network 面板的Copy as cURL再加Override。正常登录后把任意一个已认证的接口请求右键复制成 cURL拿到完整 Cookie 和 Header然后在需要的地方直接复用这一整套。这个方法的好处是它天然包含了所有隐藏的认证头不会漏。注入完成后的验证很简单刷新页面如果页面不再跳转登录页而是直接进了首页或者数据页说明注入成功。这时候你再去点几个需要权限的操作看看数据能不能正常拉出来。如果页面能进但数据拉不出来说明前端路由过了但接口鉴权没过回头检查请求头是不是漏了。2.3 第三步把注入过程固化成脚本手工注入只能解决今天我要点一下的问题要真正提效必须固化成脚本。分两种场景。场景 A前端联调时不想反复登录。最省事的办法是在项目的开发环境启动脚本里加一段注入代码或者写一个浏览器插件Tampermonkey 之类在页面加载时自动把令牌塞进去。我通常会在项目里放一个dev-token.js本地开发时在main.js里条件引入// 仅本地开发环境生效 if (import.meta.env.DEV import.meta.env.VITE_DEV_TOKEN) { localStorage.setItem(token, import.meta.env.VITE_DEV_TOKEN); localStorage.setItem(token_type, Bearer); }把令牌放在.env.local里这个文件加到.gitignore中永远不会被提交。这样做的效果是每次npm run dev起来页面直接就是已登录状态省掉每天几十次的登录动作。场景 BUI 自动化测试需要跨用例复用登录态。这里我强烈推荐用 Playwright 的storageState机制它是我目前用过最干净的方案。思路是先跑一次真实登录把登录后的存储状态存成文件后续所有测试用例直接加载这个文件跳过登录页。// setup/login.setup.js —— 只跑一次产出状态文件 const { test: setup, expect } require(playwright/test); setup(完成一次真实登录并保存状态, async ({ page }) { await page.goto(https://your-own-app.example.com/login); await page.fill(#username, process.env.TEST_USER); await page.fill(#password, process.env.TEST_PASS); // 如果测试环境有固定验证码这里一并处理 if (await page.locator(#captcha).isVisible()) { await page.fill(#captcha, process.env.TEST_CAPTCHA); } await page.click(button[typesubmit]); await expect(page).toHaveURL(/dashboard/); // 把 Cookie LocalStorage 一起落盘 await page.context().storageState({ path: state/auth.json }); });然后在playwright.config.js里把它配成一个依赖项目module.exports { projects: [ { name: setup, testMatch: /login\.setup\.js/ }, { name: chromium, use: { storageState: state/auth.json, baseURL: https://your-own-app.example.com }, dependencies: [setup] } ] };这套配置跑起来的效果是整个测试套件启动时先真实登录一次之后几百个用例全部继承这个登录态跑完整个套件只花掉一次登录的时间。我实测过一个 300 多条的用例集加上这个改造之后整轮执行时间从 18 分钟压到 11 分钟光是登录环节就省掉了 7 分钟。提示storageState文件里包含真实凭据一定要加进.gitignore并且在 CI 里通过环境变量注入账号密码不要把明文写进配置文件。我在代码评审里拦过好几次这种提交。2.4 请求拦截器让注入的令牌自动生效有些项目前端做了比较严的封装不是简单读个 LocalStorage 就完事token 存在内存变量里刷新页面就丢或者每次请求前都要重新签名。这种情况下直接注入存储往往不生效得从请求拦截器下手。以 axios 为例一个典型的拦截器长这样axios.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers.Authorization Bearer ${token}; } return config; }, error Promise.reject(error));看清这段代码之后你就会发现只要 LocalStorage 里有token请求头就会自动带上。所以问题不在注入而在于你注入的值必须通过前端自己的解析逻辑。有些项目在拦截器里会先把 token 解密或者解码验证格式格式不对就直接跳登录页。这种情况你就得把 token 的生成规则也一并复现出来。还有一种更麻烦的情况请求头里带的是签名签名 HMAC(请求参数 时间戳, 密钥)密钥硬编码在前端 bundle 里。这种设计其实防不住有心人因为前端代码是公开的。遇到这种系统我的做法是把签名逻辑用脚本复现一遍作为请求中间件挂上去。写过一次之后基本就是一劳永逸。3. 方式二服务端鉴权放行的实现路径3.1 先把鉴权链路完整拆出来方式二能不能做取决于你对服务端鉴权链路的理解深度。我一般会沿着一个请求从外到内画一遍链路搞清楚每个节点干了什么。典型的分层长这样接入层Nginx/网关负责限流和部分路由网关层Spring Cloud Gateway/API Gateway做统一鉴权校验 token 合法性应用层的过滤器或中间件再做一次细粒度鉴权判断这个用户有没有这个接口的权限业务层用PreAuthorize这类注解做方法级控制。你要做的是找到最靠外的那个校验点然后在它前面或者旁边开旁路。为什么要在最外层因为如果你只在应用层放行网关那一关还是过不去。当然反过来也有场景如果网关是共享的、不能改那只能从应用层下手这时候就要确保网关那关本身能过。我见过一种很常见的架构网关只做 token 的格式和签名校验不查库真正的这个用户存不存在、有没有权限是应用层查 Redis 做的。这种架构下如果你能拿到签名密钥测试环境的密钥通常在配置中心里就可以自己签一个合法 token把两层都过了。这也是一种自建凭据的思路比改代码更干净。3.2 实操加一个严格隔离的测试环境旁路假设是一个 Java 的 Spring Boot 项目用 Spring Security 做鉴权。我要加一个只对测试环境生效的旁路代码大概长这样Configuration Profile(test-only) // 关键只有 test-only profile 激活时才加载 public class TestAuthBypassConfig { Bean public SecurityFilterChain testFilterChain(HttpSecurity http) throws Exception { // 硬保护如果当前环境不是测试环境直接抛异常阻止启动 String active System.getProperty(spring.profiles.active, ); if (!active.contains(test-only)) { throw new IllegalStateException(测试旁路配置在非测试环境被加载进程已终止); } http.csrf().disable() .authorizeRequests() .anyRequest().permitAll(); // 测试环境全部放行 return http.build(); } }这段代码有三个要点值得展开说。要点一Profile是入口控制。只有spring.profiles.active里包含test-only时这个配置类才会被 Spring 加载。这就意味着只要测试环境的启动参数里带上这个 profile其他环境不带配置就不会生效。要点二硬保护是双保险。我在 Bean 里又加了一次运行时校验环境不对就直接抛异常让进程起不来。这不是多余——配置文件有可能被误改Profile 有可能因为版本管理混乱而串环境。抛异常是最安全的失败方式因为它会让问题在启动阶段就暴露而不是让一个无鉴权的服务静默跑起来。要点三旁路的作用范围要写死。上面这个例子里是anyRequest().permitAll()全放行。但如果测试环境里同时也跑着一些需要保护的接口就绝对不能这么写要改成精确的路径匹配比如只放行/api/test/**其他路径仍然走正常鉴权。放行范围永远要取最小值这是我给自己定的铁律。启动测试环境的时候命令加一个参数就行java -jar app.jar --spring.profiles.activetest-only然后在 CI 流水线里把这个启动参数只配置在测试环境的部署任务里。生产环境的部署任务是另一个完全独立的配置两边的流水线我建议连配置文件都不共享。3.3 自签令牌不用改代码的另一种服务端思路刚才那条路要改代码有些团队不允许在业务代码里加任何测试相关的东西。这时候有个更干净的办法自己按服务端的规则签一个合法的令牌。以最常见的 JWTHS256 算法为例它的结构是header.payload.signature三段用点号隔开前两段是 base64url 编码的 JSON。服务端校验的时候做两件事一是把前两段按同样算法算一遍 HMAC看跟第三段对不对得上二是检查 payload 里的过期时间、签发者这类字段。所以只要你能拿到密钥就能签出一个服务端认可的令牌。import jwt import datetime SECRET 从测试环境配置中心读取的密钥 payload { sub: tester-001, userId: 10086, roles: [tester], iat: datetime.datetime.utcnow(), exp: datetime.datetime.utcnow() datetime.timedelta(hours8) } token jwt.encode(payload, SECRET, algorithmHS256) print(token)Node 版本也一样简洁const jwt require(jsonwebtoken); const token jwt.sign( { sub: tester-001, userId: 10086, roles: [tester] }, process.env.TEST_JWT_SECRET, { algorithm: HS256, expiresIn: 8h } ); console.log(token);这里有个细节特别容易踩坑payload 里的字段名必须和服务端读的一致。有的框架读sub有的读username有的读自定义的uid。字段名不对令牌签名是合法的但服务端解析出来发现拿不到用户 ID照样 401。我一般会先拿一个真实令牌丢进 jwt.io 这种在线解码工具里把 payload 的字段名和格式原样抄下来再替换其中的值。这是最稳妥的做法。注意JWT 密钥属于高敏感信息。测试环境的密钥必须在配置中心独立管理绝对不能和生产的密钥相同也不能提交进代码仓库。我见过团队图省事测试和生产共用一个密钥的这相当于把生产的门锁复制了一份放在测试环境。3.4 客户端校验的绕行为什么改响应包就有效还有一种情况值得单独讲登录判定完全由前端做。这类系统的登录接口返回一个 JSON比如{code: 0, msg: success, data: {...}}前端拿到code 0就跳转首页把用户信息存 LocalStorage。整个过程中服务端并没有把令牌下发到 HttpOnly Cookie而是靠前端自己判断。这种设计的核心问题在于信任了客户端。前端拿到响应之后自己决定要不要放行那么只要你能改掉这个响应前端就会被骗过去。在浏览器里改响应有三种方式都只能在你自己的浏览器上生效用于调试自己的项目第一种是请求拦截插件比如一些浏览器扩展支持在本地配置请求/响应的改写规则把code从1改成0。第二种是本地反向代理用 mitmproxy 这类工具在你和服务器之间架一层写个脚本拦截特定 URL 的响应并改写。第三种是纯前端 Hack在控制台里重写 fetch 或者 XHR 的响应处理函数。我用得最多的是第二种因为它可以脚本化、可复用。一个简单的改写脚本大概是这样# mitmproxy 的 addon 脚本仅用于自有系统的本地调试 from mitmproxy import http import json class MockLoginResult: def response(self, flow: http.HTTPFlow): if /api/user/login in flow.request.pretty_url: body json.loads(flow.response.text) body[code] 0 body[data] { userId: 10086, userName: tester, roles: [ADMIN] } flow.response.text json.dumps(body) flow.response.headers[content-length] str(len(flow.response.text)) addons [MockLoginResult()]跑起来之后用mitmproxy -s mock_login.py启动把浏览器的代理指向本地端口所有发往登录接口的响应都会被改写。但是这种方式有一个根本性的局限它只能骗过前端。一旦你点击任何一个真正需要数据的接口服务端该 401 还是 401因为它从来没收到过合法凭据。所以这种改响应包的做法只适合做前端页面的功能验证比如你只想看看某个报表页面长什么样、布局有没有错乱、大数据量下渲染会不会卡那它可以帮你省掉等待后端提供测试账号的时间。想用它来真正拿到数据是走不通的。提示正因为这条路走不通反过来也说明了服务端鉴权的重要性。如果你自己在做系统看到登录判定放在前端做的设计一定要提出来改掉。判定必须在服务端前端只负责展示。4. 两种方式怎么选、怎么组合4.1 一份实用的选型决策表我把选型的判断逻辑整理成了下面这张表。实际决策的时候从上往下问遇到第一个能满足的就停。你的情况推荐方式理由想省掉每天反复登录的时间方式一本地注入脚本成本最低几分钟搞定做 UI 自动化测试方式一storageState复用真实凭据结果可信做接口自动化测试方式一令牌注入请求头不需要浏览器更轻量只验证前端页面渲染方式一 响应改写后端没准备好数据时的过渡方案压测需要大量并发用户方式二测试环境旁路方式一逐个登录太慢集成测试需要固定身份方式二自签令牌身份可控便于构造用例演示环境需要免登录方式二精确路径放行演示场景只需要看不要操作这张表里我最想强调的是最后两行。给演示环境做免登录其实是很多团队的刚需——展厅的大屏、客户演示的临时环境让参观者自己输账号不现实。但这时候的放行范围一定要精确到路径而且最好加一层来源 IP 限制只允许展厅的固定网络访问。这两个约束叠加起来风险就控制得很好了。4.2 组合使用的实际案例纯粹只用一种方式的项目其实不多我最近手头的一个项目就是组合起来的讲一下思路你可以对照参考。这个项目是个后台管理系统有 PC 端和移动端两套前端服务端是网关加微服务的结构。测试团队有 40 多号人日常要跑回归测试还有一条每晚上跑的接口自动化流水线。我的方案是这样搭的日常手工测试用方式一每个人配一套自己的令牌注入脚本用自己的账号登录一次拿到令牌之后本地开发环境的页面就是免登录状态。这样每个人看到的权限、能操作的数据都是自己账号的真实情况测试结果不会被污染。接口自动化流水线用方式二的自签令牌。流水线跑在独立的测试环境环境里配了一份独立的 JWT 密钥。测试框架启动时根据用例需要的角色动态签出不同角色的令牌比如一个用例需要管理员权限就签管理员令牌需要普通用户就签普通用户。这样一条流水线可以覆盖多种权限组合的用例不需要为每个角色准备一个真实账号。UI 自动化用方式一的 storageState但登录账号是从环境变量里读的而且用的是专门给自动化用的测试账号。这个账号的权限被限制在只读范围即使状态文件泄露也造成不了什么损害。演示环境用方式二的精确放行只放行了首页和几个展示页面的 GET 接口同时在网关层加了来源 IP 白名单。写操作一个都没放。这套组合跑了一年多没出过事故。核心经验就是每种方式用在它最擅长的地方不要让一种方式承担全部需求。5. 踩坑实录与常见问题排查5.1 常见问题速查表下面这些问题都是我或者身边同事真实遇到过的我按现象、原因、解决三步整理成表你可以直接当速查手册用。现象可能原因排查与解决注入后刷新还是跳登录页存储 key 名不对或存的是别的域名在 Network 里找已认证请求看实际带了什么逐字比对页面能进但接口 401令牌只注入了存储没进请求头检查拦截器逻辑或手工加 Authorization 头测试令牌注入生效但半小时后失效只有 access token缺 refresh token两个都注入或实现自动刷新逻辑每次请求都要重新登录令牌存在内存变量里刷新即丢从拦截器层介入或复现令牌生成逻辑storageState 复用后偶发失败令牌在测试执行中途过期缩短套件时长或在 setup 里把有效期设长自签令牌服务端返回签名错误算法不匹配HS256 用了 RS256 密钥解码真实令牌的 header看 alg 字段是什么自签令牌签名对但 401payload 字段名与服务端读取的不一致用在线工具解码真实令牌逐字段对齐测试旁路在生产生效Profile 或环境变量串了加运行时硬校验环境不对直接抛异常改响应包后仍无法跳转前端还校验了其他字段或发了后续请求完整观察所有响应逐个补齐跨域场景下 Cookie 带不上SameSite 策略限制检查 SameSite 值必要时改为独立域名这张表里每次请求都要重新登录和测试旁路在生产生效这两条我要额外强调。前者是纯技术问题解法是靠理解前端实现后者是工程纪律问题解法只有一个——把环境隔离做到物理级别两份配置连目录都不放在一起。5.2 几条只有踩过才知道的经验经验一先看 Network再动手写代码。我刚开始做这块的时候总喜欢凭经验去猜 token 存哪、叫什么名字结果十次有八次猜错。后来我强制自己养成一个习惯不管多简单的项目先花五分钟把 Application 面板和 Network 面板翻一遍把实际数据抄下来再动手。这个习惯让我的平均处理时间从一小时降到了十分钟。经验二令牌不是越长效越好。有人为了省事把自签令牌的有效期设成 30 天。这在测试环境里看起来很方便但一旦这个令牌泄漏或者被误用暴露窗口就太大了。我的做法是有效期设 8 小时覆盖一个完整工作日同时脚本里实现自动续签。这样既省事又把风险控制在一个可控的范围内。经验三给所有的注入脚本加显眼的日志。这类脚本通常放在本地容易被忘记。我见过同事几个月后忘了自己注入过令牌排查一个为什么这个账号权限不对的问题查了一下午。所以我现在写这类脚本启动时一定要打一行醒目的日志比如[DEV-TOKEN] 已注入开发环境测试令牌来源 xxx。看到日志就知道当前是注入状态。经验四区分调试用和测试用两套令牌。调试用的令牌是我自己的账号权限完整用来看各种边界情况测试用的令牌是专用账号权限最小化用在自动化脚本里。这两套永远不混用也不共用同一个配置文件。这样做的目的是即使自动化脚本的配置泄漏了也不会牵连到我自己的账号。经验五改响应包这件事永远只当临时手段。我前面讲过它只能骗前端。实际项目里我的使用边界是只在后端接口还没开发完、但我需要验证前端页面渲染效果的时候用用完立刻撤掉。绝不把它作为长期方案因为一旦形成依赖团队就会误以为登录流程没问题忽略了服务端鉴权可能存在的缺陷。5.3 从被绕过反推自己系统的防线聊完了怎么绕过我更想说说怎么防止自己的系统被绕过。这部分其实更有价值因为它直接关系到你系统的安全水位。我给自己负责的系统定了几条硬规矩。第一条永远不在前端做登录判定。登录接口的返回值只用来做 UI 展示页面跳转由服务端下发的会话状态决定。用户能不能访问某个页面前端路由做的那一层只是体验优化真正的拦截必须在服务端。第二条令牌一律用 HttpOnly Cookie 存。这样 JavaScript 就读不到XSS 攻击拿不到令牌。第三条所有敏感接口做二次鉴权。光有 token 不够还要检查这个 token 对应的用户有没有这个资源的访问权限不能出现登录了就能看所有数据的情况。第四条令牌有效期尽量短配自动续签。减少凭证泄漏后的可用窗口。第五条全部接口记录审计日志谁的令牌在什么时候访问了什么都要留痕。这五条下来前面讲的那些手段基本就都失效了。最后还有一条我特别想说的定期用攻击者的思路检查自己的系统。我会每隔一段时间自己用上面讲的方式一和方式二试着从外部访问一下自己的生产环境看看有没有哪里漏了。这个动作在正规的安全流程里叫渗透测试但如果你是开发自己定期做一遍轻量版的收益非常大。我在自己的项目上就靠这个发现过一次 Cookie 里带了过长的有效期、一次是某个内部接口没走网关鉴权都是在造成实际影响之前修掉的。这两件事我个人的体会是绕过登录这个动作本身没有好坏它取决于你用在什么地方。用在提效和测试上它是把好用的刀用在别人的系统上那就是另一回事了。你手上如果是自己负责的系统、或者是明确授权的测试环境上面这些方法你可以直接用效果我实测过很多次。但如果哪天有人让你去看看这个网站能不能进先问清楚授权文件在哪里这个问题比技术本身重要得多。
返回列表