第 7 章 · 01 框架专项(Django / FastAPI / NestJS / Nex...


文档摘要

第 7 章 · 01 框架专项(Django / FastAPI / NestJS / Next.js) 本节摘要:通用 Web 漏洞讲的是「面」,框架专项讲的是「点」。每个主流 Web 框架都有自己的特有攻击面:Django 的 会把 、数据库连接串、已装应用一股脑塞进黄色调试页;FastAPI 默认把 当成生产接口暴晒;NestJS 的守卫栈(global → controller → method)只要某个 handler 漏挂 就敞开大门;Next.js 的 Server Action 鉴权常常依赖客户端状态而非服务端强制。本节合并 Django、FastAPI、NestJS、Next.

第 7 章 · 01 框架专项(Django / FastAPI / NestJS / Next.js)

本节摘要:通用 Web 漏洞讲的是「面」,框架专项讲的是「点」。每个主流 Web 框架都有自己的特有攻击面:Django 的 DEBUG=True 会把 SECRET_KEY、数据库连接串、已装应用一股脑塞进黄色调试页;FastAPI 默认把 /openapi.json 当成生产接口暴晒;NestJS 的守卫栈(global → controller → method)只要某个 handler 漏挂 @UseGuards 就敞开大门;Next.js 的 Server Action 鉴权常常依赖客户端状态而非服务端强制。本节合并 Django、FastAPI、NestJS、Next.js 四个框架的安全测试要点,聚焦「配置泄露点、错误配置、栈特有攻击面」,让你在真实目标上精准命中框架的软肋。

⚠️ 仅限授权测试:本节所有技术仅用于你自己的应用或有书面授权的渗透测试。未经授权对他人系统使用这些技术是非法的。

学习目标

阅读完本节,你应当能够:

  1. 识别 Django 的配置泄露点(DEBUGSECRET_KEYALLOWED_HOSTS)与 DRF 序列化器/权限类缺口。
  2. 掌握 FastAPI 的依赖注入鉴权漂移、Pydantic 字段策略、OpenAPI 信息泄露。
  3. 理解 NestJS 守卫栈断点、Validation Pipe 绕过、多传输(HTTP/WS/微服务)鉴权不一致。
  4. 识别 Next.js 的中间件绕过、Server Action 鉴权、RSC/缓存边界、__NEXT_DATA__ 过度暴露。
  5. 在每个框架上执行「角色矩阵 × 传输矩阵 × 内容协商」的系统化测试。
  6. 区分「框架默认帮你挡的」与「框架留给你自己配、但你忘了配的」。

一、Django

Django 的默认相对安全(CSRF 中间件、模板自动转义),但 DRF、原始 SQL、自定义权限、部署配置常常引入缺口。攻击面集中在四块:配置泄露、权限/会话、注入、序列化器与对象级权限。

1.1 攻击面与高价值目标

  • 核心组件:urls.py 路由、类视图与函数视图、中间件栈;ORM(filterQextraRawSQL);模板(Django 模板 / Jinja2 后端);表单与 DRF 序列化器。
  • 认证:Session 框架、AuthenticationMiddleware@login_required、DRF permission_classes;Token / JWT(djangorestframework-simplejwt);Django admin(/admin/)。
  • 部署:DEBUG=True 暴露、ALLOWED_HOSTSSECRET_KEY 泄露;静态/媒体服务、反向代理、ASGI(Channels / Daphne / Uvicorn)。
  • 高价值目标:/admin/(爆破、撞库、对象 IDOR);混合权限类的 ViewSet;文件上传与导入导出(django-import-export);搜索/过滤端点(filter()Q、原始 SQL);密码重置/邀请令牌;WebSocket consumers(常比 HTTP 鉴权更弱);Celery 任务接收用户 ID 但不校验归属。

1.2 典型缺陷:配置泄露点

Django 最经典的栈特有问题就是 DEBUG=True 进了生产。触发任意异常后,黄色调试页会泄露:

  • SECRET_KEY(可伪造签名 cookie、密码重置令牌)
  • 数据库连接串(用户名、主机、库名)
  • 已安装应用列表、完整堆栈、模板搜索路径、ORM 查询语句

指纹与探测:

curl -I https://target/ -H "Cookie: sessionid=test" # 关注 X-Frame-Options、Set-Cookie(sessionid/csrftoken)、Server 头 GET /admin/login/ GET /api/ /api/v1/ /swagger/ /api/schema/

/static/、带堆栈的错误页同样会暴露路径与 ORM 查询。DRF 的 OpenAPI 也是金矿:

GET /api/schema/ GET /swagger.json

可逐路由映射 authentication_classespermission_classes,直接找出哪些路由没挂权限。

1.3 认证与授权缺陷

权限类缺口:ViewSet 常见「保护了 list、忘了 retrieve/update」;自定义权限只校验「是否登录」不校验「对象归属」(IDOR);@api_view 不显式声明权限就继承宽松默认值;admin 动作或自定义管理命令不带 staff 校验。

会话问题:SESSION_COOKIE_SECURE=False(HTTPS 站点)、缺 HttpOnly;登录后未轮换 session key(会话固定);SECRET_KEY 弱或泄露 → 伪造会话 cookie(尤其是 signed_cookies 后端)。

JWT(simplejwt):RS256→HS256 算法混淆(未钉死算法时);登出未把 user_id/token 拉黑;刷新令牌未强制轮换。

1.4 注入面

ORM SQL 注入(老代码常见):

User.objects.raw(f"SELECT * FROM auth_user WHERE username = '{user_input}'") User.objects.extra(where=[f"username = '{user_input}'"])

测试 payload:' OR 1=1 --、时间盲注、数据库特定语法。

DRF 过滤后端:django-filter 字段暴露不安全,如 ?username__icontains= 打到非预期列;?ordering= 注入(字段白名单缺失时)。

模板注入:Django 模板默认自动转义,危险来自:

mark_safe(user_input) |safe 过滤器 Template(user_input).render(...) # 用户控制模板源 → SSTI

Jinja2 后端关闭自动转义时,{{7*7}} 即可触发,沙箱配错则有 RCE gadget。

1.5 CSRF、IDOR 与批量赋值

CSRF:@csrf_exempt 标在状态变更视图上;DRF 会话认证对不安全方法不强制 CSRF;CSRF_TRUSTED_ORIGINS 过宽。测试:跨源 POST 携带受害者会话 cookie,JSON 端点 + 会话认证尤其要测。

DRF 序列化器:fields = '__all__' 暴露 is_staffis_superuserrolebalance;敏感字段缺 read_only_fields;嵌套写跨租户更新外键。

对象级权限:get_object() 未按 request.user 过滤 queryset;通用视图 queryset = Model.objects.all() 配弱权限。

1.6 利用与验证

  1. 旁路请求对比:非授权访问(IDOR、提权)用 A/B 账号对同一资源发请求,内容差异即证据。
  2. CSRF PoC:在受害者会话下执行状态变更。
  3. 注入确定性 oracle:报错、时间、或 7*7 等价物。
  4. 记录失效的视图/序列化器/权限类路径。
  5. 若普通用户拿到 admin/staff 能力,单独标注。

1.7 工具与白盒

沙箱自带 python/pipxsemgrepbanditast-grepripgrep:

  • bandit -r . -ll — 标记 mark_safeextra()RawSQL、弱加密、硬编码密钥。
  • semgrep --config p/django . — 比 bandit 更针对框架(.extra()RawSQL|safecsrf_exemptALLOWED_HOSTS=['*'])。
  • ast-grep run -p 'mark_safe($X)' -l python — 结构化快速 grep。
  • pip-audit — 依赖 CVE 扫描 Django/DRF/simplejwt 版本。

💡 Pro Tips:DRF ViewSet 常保护 list 却忘了 destroy 或自定义 @action;APIView 子类缺 permission_classes 是高频疏漏;?format= 与可浏览 API 的 HTML 响应在会话认证下要测 CSRF;django.contrib.admin 用独立认证,别假设 API 认证覆盖 admin;ASGI WebSocket consumer 要和 REST 同资源的权限对比。

二、FastAPI

FastAPI/Starlette 的攻击面集中在:依赖注入鉴权漂移、OpenAPI 信息泄露、Pydantic 输入处理、CORS/CSRF、代理与 Host 信任、模板注入、SSRF、WebSocket 与挂载子应用。

2.1 攻击面与高价值目标

  • 核心组件:ASGI 中间件(CORS、TrustedHost、ProxyHeaders、Session、异常处理器、lifespan);路由与子应用(APIRouter 前缀/标签、挂载 StaticFiles、admin、include_router、版本化路径);依赖注入(DependsSecurityOAuth2PasswordBearerHTTPBearer、scopes)。
  • 数据层:Pydantic 模型(v1/v2、union/Annotated、自定义校验器、extra 字段策略、类型强制);UploadFile/File/FileResponse/StaticFiles;Jinja2Templates
  • 通道:HTTP(同步/异步)、WebSocket、SSE/StreamingResponse;BackgroundTasks 与任务队列。
  • 高价值目标:生产环境的 /openapi.json/docs/redoc(完整攻击面地图、securitySchemes、server URL);token 端点、会话/cookie 桥接、OAuth device/PKCE;admin/staff 路由、feature-flag 路由、include_in_schema=False 的端点;文件上传/下载、导入导出、签名 URL 生成器;WebSocket 端点;后台任务端点(/jobs/{id});挂载子应用(admin UI、存储浏览器、metrics)。

2.2 典型缺陷:OpenAPI 信息泄露与依赖映射

FastAPI 默认把 OpenAPI 暴晒。生产环境若未关闭:

GET /openapi.json GET /docs GET /redoc GET /api/openapi.json GET /internal/openapi.json

提取 paths、parameters、securitySchemes、scopes、servers。include_in_schema=False 的端点不会出现——按已发现前缀和常见 admin/debug 名 404 fuzz。

依赖映射是 FastAPI 鉴权测试的核心。对每条路由,识别:

  • 路由级依赖(作用于全部路由)
  • 路由项级依赖(单端点)
  • 哪些依赖是「强制鉴权」,哪些只是「解析输入」

2.3 认证与授权漂移

依赖注入缺口:路由漏挂其他路由都有的安全依赖;用 Depends 而非 Security(忽略 scope 强制);「token 存在」被当成「已认证」而不验签;OAuth2PasswordBearer 只吐 token 字符串——要确认路由没把「存在」当鉴权。

JWT 误用:解码不验签(测无签名 token、攻击者签名 token);算法混淆(HS256/RS256 未钉死);kid 头注入到自定义 key 查找路径;缺 issuer/audience 校验、跨服务 token 复用。

会话弱配:SessionMiddleware 用弱 secret_key;可预测签名导致的会话固定;cookie 鉴权缺 CSRF 保护。

2.4 访问控制与输入处理

IDOR via 依赖:路径/查询里的对象 ID 未按调用者校验;租户 header 被信任却未绑定到已认证用户;BackgroundTasks 操作 ID 时执行期未重新校验归属;导入导出流水线 IDOR 与跨租户泄露。

Scope 绕过:最小 scope 满足(任何合法 token 都接受);路由级 vs 路由项级 scope 强制不一致。

Pydantic 利用:类型强制(string→int/bool、空串→None、truthiness 边界);extra = "allow" 允许注入控制字段(role、ownerId、scope);union/Annotated 构造命中非预期校验分支。

Content-Type 切换:

application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data

不同 content-type 命中不同校验器或代码路径(解析器差异)。头部/cookie 名大小写变体、重复参数利用 DI 优先级、X-HTTP-Method-Override 方法覆盖(上游尊重、应用不尊重)都是常见绕过。

2.5 CORS、CSRF、代理信任

CORS 错配:allow_origin_regex 过宽;Origin 反射不校验;带凭证的请求配宽松 origin;对比 preflight 与真实请求的差异。

CSRF 暴露:FastAPI/Starlette 无内置 CSRF;cookie 鉴权缺 origin 校验;缺 SameSite。

头部伪造:无网络边界的 ProxyHeadersMiddleware——伪造 X-Forwarded-For/Proto 影响鉴权/IP 门控;缺 TrustedHostMiddleware 的 Host 头投毒(密码重置链接、绝对 URL 生成);缓存 key 混淆(缺 Vary on Authorization/Cookie/Tenant)。

2.6 服务端漏洞与挂载子应用

模板注入(Jinja2):

{{7*7}} # 算术确认 {{cycler.__init__.__globals__['os'].popen('id').read()}} # RCE

检查自动转义与自定义 filter/global。

SSRF:导入/预览/webhook 校验中的用户 URL;测 loopback、RFC1918、IPv6、重定向、DNS rebinding、头部控制;httpx/requests 的重定向策略、头部转发、协议支持;file://ftp://、gopher 类垫片(自定义 client 时)。

文件上传:UploadFile.filename 含控制字符的路径穿越;缺存储根强制、跟随符号链接;变体文件名编码、点段、NUL 类字节。

WebSocket:缺每连接认证;跨源 WebSocket 无 origin 校验;topic/channel IDOR(订阅他人 channel);只在握手鉴权、不逐消息。

挂载子应用:/admin/static/metrics 的子应用可能绕过全局中间件。验证所有挂载点的鉴权对等。若挂了 GraphQL(Strawberry/Graphene),验证 resolver 级鉴权与 node/global ID 的 IDOR;若有 SQLModel/SQLAlchemy,探原始查询与行级鉴权缺口。

2.7 验证

  • 旁路请求证明非授权访问(归属者 vs 非归属者、跨租户)。
  • 跨通道证明(同一规则的 HTTP 与 WebSocket)。
  • 头部/代理操纵改变结果(Host/XFF/CORS)。
  • 模板注入、SSRF、token 误用的最小 payload + OAST oracle。
  • 记录漏挂强制的精确依赖路径(路由级、路由项级)。

💡 Pro Tips:FastAPI 的「依赖存在 ≠ 鉴权存在」——Depends(get_token) 只是把 token 取出来,验签和授权是你自己的事;/docs 在 dev 司空见惯,在 prod 就是攻击面地图;Pydantic 的 extra="allow" 是隐形批量赋值。

三、NestJS

NestJS 的攻击面集中在:装饰器栈(global → controller → method)的守卫断点、Validation Pipe 绕过、模块边界泄露、跨传输(HTTP/WebSocket/微服务)鉴权不一致。

3.1 攻击面与高价值目标

  • 装饰器流水线:守卫(@UseGuardsCanActivate、执行上下文 HTTP/WS/RPC、Reflector 元数据);管道(ValidationPipe 的 whitelist/transform/forbidNonWhitelisted、ParseIntPipe、自定义 pipe);拦截器(响应映射、缓存、日志、超时);过滤器(可能泄露信息的异常过滤器);元数据(@SetMetadata@Public()@Roles()@Permissions())。
  • 模块系统:@Module 边界、provider 作用域(DEFAULT/REQUEST/TRANSIENT);动态模块 forRoot/forRootAsync;DI 容器(provider override、自定义 provider)。
  • 控制器与传输:REST(@Controller、版本化 URI/Header/MediaType);GraphQL(@Resolver、playground/sandbox 暴露);WebSocket(@WebSocketGateway、gateway 守卫、room 鉴权);微服务(TCP、Redis、NATS、MQTT、gRPC、Kafka——常缺 HTTP 级鉴权)。
  • 数据层:TypeORM(repository、QueryBuilder、原始查询、relations);Prisma($queryRaw$queryRawUnsafe);Mongoose(操作符注入、$where$regex)。
  • 认证与配置:@nestjs/passport 策略、@nestjs/jwt、会话认证;@nestjs/config、ConfigService、.env;@nestjs/throttler@SkipThrottle;@nestjs/swagger(OpenAPI 暴露、DTO schema、auth scheme)。
  • 高价值目标:生产 Swagger/OpenAPI(/api/api-docs/api-json/swagger);认证端点(登录、注册、刷新、密码重置、OAuth 回调);带 @Roles('admin') 的 admin 控制器(用 user 级 token 测);FileInterceptor/FilesInterceptor 上传;共享业务逻辑的 WebSocket gateway;@MessagePattern/@EventPattern 微服务 handler(常无守卫);CRUD 生成器(@nestjsx/crud);后台任务与定时任务(@nestjs/schedule);健康/metrics(/health/metrics);GraphQL playground(/graphql)。

3.2 典型缺陷:守卫栈断点

NestJS 鉴权的头号缺陷就是装饰器栈缺口:

  • 守卫执行顺序 global → controller → method。某个 method 漏挂 @UseGuards(兄弟方法都挂了)是头号发现。
  • @Public() 元数据让全局 AuthGuard 跳过——检查是否应用过宽。
  • 已有控制器上新增 method 却没继承预期守卫。

ExecutionContext 切换:只处理 HTTP 上下文(getRequest())的守卫,在 WebSocket 或 RPC 上可能静默失败、默认返回 true。同一业务逻辑走不同传输,常能找到上下文专属绕过。

Reflector 不匹配:守卫读 SetMetadata('roles', [...]) 但装饰器写的是 'role'(单数)——守卫看不到元数据,默认放行。applyDecorators() 组合可能意外用宽松守卫覆盖严格守卫。

3.3 Validation Pipe 绕过

Whitelist 绕过:whitelist: true 但没 forbidNonWhitelisted: true——额外属性被静默剥离,但可能已被更早的中间件/拦截器处理。嵌套对象缺 @Type(() => ChildDto):@ValidateNested() 不配 @Type 等于嵌套 payload 完全不校验。数组:@IsArray() 不配 @ValidateNested({ each: true }) + @Type 不校验元素。

类型强制:transform: true 开启隐式强制(string→number、"true"true"null"null);利用下游业务逻辑的 truthiness 假设。

条件校验:@ValidateIf() 与校验组造出字段完全跳过校验的路径。

缺 Parse Pipe:@Param('id') 不配 ParseIntPipe/ParseUUIDPipe——字符串值直达 ORM 查询。

3.4 认证、序列化与拦截器

JWT 策略:检查 ignoreExpiration 是否 false、algorithms 是否钉死(无 none 或 HS/RS 混淆);弱 secretOrKey;跨服务 token 复用(audience/issuer 未强制)。

Passport 策略问题:validate() 返回值变成 req.user——若返回完整 DB 记录,敏感字段向下游泄露;多策略(JWT + 会话)可能互相绕过限制;自定义守卫对未认证返回 true 当「可选认证」。

计时攻击:本地策略用明文字符串比较而非 bcrypt/argon2。

序列化泄露:未全局应用 ClassSerializerInterceptor 时,@Exclude() 字段(密码、内部 ID)被返回;@Expose() 配组时,admin 专属字段在未按请求强制组时暴露;eager 加载的 TypeORM/Prisma 关系暴露整个对象图。

拦截器滥用:CacheInterceptor 不把用户/租户身份放进缓存 key——一个用户的响应发给另一个(先认证请求、再未认证请求拿缓存);响应映射拦截器映射不全则泄露内部实体字段。

3.5 模块边界与多传输

全局模块暴露:@Global() 模块把所有 provider 暴露给每个模块,无需显式 import;敏感服务(admin 操作、内部 API)从不可信模块可达。

配置泄露:forRoot/forRootAsync 的配置密钥,可通过任意模块注入 ConfigService 访问。

作用域问题:REQUEST 作用域 provider 误配成 DEFAULT(单例)——请求上下文在并发请求间泄露。

WebSocket Gateway:HTTP 守卫不会自动应用到 WebSocket gateway——@UseGuards 必须显式;鉴权从 handleConnection 延迟到消息 handler,允许未认证发消息;room/namespace 鉴权:用户加入不该访问的 room;@SubscribeMessage() handler 依赖连接级认证而非逐消息校验。

微服务传输:@MessagePattern/@EventPattern handler 常无守卫(被视为「内部」);若传输(Redis、NATS、Kafka)网络可达,可注入消息绕过全部 HTTP 安全;ValidationPipe 可能只配 HTTP——微服务 payload 跳过校验。

3.6 ORM 注入、限流与 CRUD 生成器

TypeORM:QueryBuilder.query() 用模板字符串插值 → SQL 注入;relations:API 允许通过查询参数指定加载哪些关系。

Mongoose:查询操作符注入({ password: { $gt: "" } } 经未净化请求体);$where$regex 来自用户输入。

Prisma:$queryRaw/$executeRaw 用字符串插值(非 tagged template);$queryRawUnsafe

限流:敏感端点(登录、密码重置、OTP)上的 @SkipThrottle();内存 throttler 存储:重启即重置、跨实例失效;代理后未 trust proxy:所有请求共享同一 IP,或头部可伪造。

CRUD 生成器:自动生成的 CRUD 端点可能不继承手工守卫配置;批量操作(createManyupdateMany)绕过逐实体鉴权;CRUD 库的查询参数注入(filtersortjoinselect)暴露非授权数据。

3.7 绕过与验证

绕过手法:@Public() / 跳过元数据经组合装饰器在 method 级应用,使全局守卫经 Reflector 元数据检查跳过;路由参数污染 /users/123?id=456(守卫 vs handler 谁的 id 胜出?);版本路由 v2 加了守卫、v1 没加;X-HTTP-Method-Override_method 在守卫之前被 Express 处理;content-type 切换绕过 JSON 专属校验;异常过滤器差异:守卫抛错变成泛化错误,泄露路由存在性。

验证要求:守卫绕过(无认证请求访问受保护端点成功,展示守卫链断点);校验绕过(额外/畸形字段影响业务逻辑);跨传输不一致(同一操作 HTTP 鉴权但 WebSocket/微服务可利用);模块边界泄露;序列化泄露(响应含 @Exclude 字段);IDOR(两用户旁路请求);ORM 注入;缓存投毒。

💡 Pro Tips:NestJS 的「守卫存在 ≠ 守卫生效」——@Public() 一行注释就能让全局守卫跳过;WebSocket 和微服务 handler 是 HTTP 守卫的盲区,务必走一遍同样业务逻辑的 WS/RPC 路径;ValidationPipewhitelist 不配 forbidNonWhitelisted 是「静默吞字段」,看起来安全实则已被拦截器处理过。

四、Next.js

Next.js 的攻击面集中在:运行时(Edge/Node)鉴权漂移、缓存边界、Server Action、中间件绕过。App Router 与 Pages Router 常共存,鉴权可能在两套路由间不一致。

4.1 攻击面与高价值目标

  • 路由器:App Router(app/)与 Pages Router(pages/)常共存;Route Handler(app/api/**)与 API 路由(pages/api/**);项目根的 middleware.ts
  • 运行时:Node.js(完整 API);Edge(V8 isolate,受限 API)。
  • 渲染与缓存:SSR、SSG、ISR、按需重验证;RSC(React Server Components)配 fetch 缓存;draft/preview 模式。
  • 数据通路:Server Components、Client Components;Server Action(带 Next-Action 头的流式 POST);getServerSidePropsgetStaticProps
  • 集成:NextAuth.js(回调、CSRF、callbackUrl);next/image 优化与远程 loader。
  • 高价值目标:中间件保护的路由(认证、地理、A/B);admin/staff 路径、draft/preview 内容、按需重验证端点;RSC payload与 flight data、流式响应;图片优化器与自定义 loader、remotePatterns/domains;NextAuth 回调(/api/auth/callback/*)、登录 provider;Edge 专属功能(bot 保护、IP 门控)及其 Node 等价物。

4.2 侦察:路由与构建产物

Next.js 的侦察很大程度靠客户端 bundle 挖掘:

// 浏览器控制台 - 列出所有路由 console.log(__BUILD_MANIFEST.sortedPages.join('\n')) // 检查服务端取的数据 JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props.pageProps // 列出公开环境变量 Object.keys(process.env).filter(k => k.startsWith('NEXT_PUBLIC_'))

构建产物:

GET /_next/static/<buildId>/_buildManifest.js GET /_next/static/<buildId>/_ssgManifest.js GET /_next/static/chunks/pages/ GET /_next/static/chunks/app/

chunk 文件名映射到路由(如 admin.js/admin)。检查 /_next/static/ 下是否有暴露的 .map 文件,泄露路由结构、server action ID、内部函数。

客户端 bundle 挖掘:在 main-*.js 搜 pathname:href:__next_route__serverActions、API 端点;grep API_KEYSECRETTOKENPASSWORD 找意外泄露的凭证。

Server Action 发现:Network 面板看带 Next-Action 头的 POST,从响应流和水合数据提取 action ID。

额外泄露:/sitemap.xml/robots.txt/sitemap-*.xml 找非预期 admin/internal/preview 路径;客户端 bundle/env 找秘密路径与 preview/admin 标志(很多团队只用 UI 隐藏路由)。

4.3 典型缺陷:中间件绕过

已知技术:x-middleware-subrequest 头构造(CVE 级绕过);x-nextjs-data 探测;留意 307 + x-middleware-rewrite/x-nextjs-redirect 头。

路径规范化:

/api/users /api/users/ /api//users /api/./users

中间件的规范化可能与路由处理器不同。测双斜杠、尾斜杠、点段。

参数污染:?id=1&id=2?filter[]=a&filter[]=b——中间件查第一个值,handler 用最后一个或数组。

4.4 Server Action 与 RSC/缓存

Server Action:在 UI 流程外用替代 content-type 调用 action;鉴权依赖客户端状态而非服务端强制;action payload 里的对象引用导致 IDOR;从 source map 映射 action ID 发现隐藏 action。

缓存边界失败:用户绑定数据无身份 key 缓存(无 ETag/Set-Cookie 感知);个性化内容从共享缓存/CDN 提供;敏感 fetch 缺 no-store

Flight Data 泄露:检查流式 RSC payload 的 props 里序列化的敏感字段。

ISR 问题:stale-while-revalidate 响应含用户专属或租户相关数据;按需重验证端点 URL 的弱密钥;Referer 泄露的 token 或未校验 host 触发 revalidatePath/revalidateTag;头部走私或方法变体触发重验证。

4.5 认证与数据暴露

NextAuth 陷阱:每个 provider 缺/松 state/nonce/PKCE(登录 CSRF、token 混淆);callbackUrl 开放重定向或 allowed hosts 范围过宽;跨路由未强制 JWT audience/issuer;跨服务 token 复用;强制回调劫持会话。

会话边界:App Router 与 Pages Router 之间鉴权不一致;API 路由 vs Route Handler 鉴权不一致。

__NEXT_DATA__ 过度获取:服务端取的数据传给客户端却不渲染——只需要用户名却传整个 user 对象;内部 ID、token、admin 专属字段;ORM select-all 模式暴露整条记录;API 响应未净化转发(元数据、游标、调试信息)。

环境相关暴露:staging/dev 意外暴露比 prod 更多字段;跨环境序列化逻辑不一致。

Props 检查:

JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props

_metadata_internal__typename(GraphQL)、嵌套敏感对象。

4.6 图片优化器 SSRF、运行时分叉、客户端

Remote Patterns:next.config.js 里宽泛的 images.domains/remotePatterns;测内部主机、IPv4/IPv6 变体、DNS rebinding。

自定义 Loader:重定向链的协议走私;URL 规范化差异影响其他用户的缓存投毒。

运行时分叉(Edge vs Node):依赖 Node 专属模块的防御在 Edge 上被跳过;头部信任不同(x-forwarded-* 处理);同一路由跨运行时行为不同。

客户端 XSS:dangerouslySetInnerHTML;Markdown 渲染器;用户可控 href/src 属性;验证 SSR/CSR/hydration 的 CSP/Trusted Types 覆盖;服务端 vs 客户端渲染差异可启用 gadget 型 XSS。

Draft/Preview 模式:启用 preview 的秘密 URL/cookie;preview 密钥泄露在客户端 bundle/env;从子域或经开放重定向设置 preview cookie。

4.7 验证

  • 旁路请求展示跨用户/租户访问。
  • 缓存边界失败证明(响应差异、ETag 碰撞)。
  • Server Action 在 UI 外以不足鉴权调用。
  • 中间件绕过用显式头部展示受保护内容访问。
  • 运行时对等检查(Edge vs Node 强制不一致)。
  • 发现的路由验证为已部署(200/403),而非仅构建产物(404)。
  • 泄露凭证用最小只读调用测试,过滤占位符。
  • __NEXT_DATA__ 暴露:验证跨用户(用户 A 的 props 不该含用户 B 的 PII),确认暴露字段不在 DOM。
  • 路径规范化绕过:展示差异响应(403 vs 200),重定向不算。

💡 Pro Tips:Next.js 的中间件是「请求级」的,路由处理器是「处理级」的——两者路径规范化不一致就是绕过;__NEXT_DATA__ 是被低估的金矿,很多团队把整条 ORM 记录塞进去;Server Action 的鉴权常常「假设客户端不发就不会调」,实际只要有 action ID 就能 POST。

本节要点回顾

  1. Django 配置泄露:DEBUG=True 进生产 = 黄色调试页泄露 SECRET_KEY/DB 连接串/已装应用;DRF 的 /api/schema/ 是逐路由权限地图。
  2. Django 权限缺口:ViewSet 保护 list 忘了 destroy;fields='__all__' 暴露 is_staff/is_superuser;get_object() 不按 request.user 过滤 = IDOR。
  3. Django 注入面:.raw(f"...{user_input}...").extra(where=[...])mark_safe()|safeTemplate(user_input).render() 是四大嫌疑点;bandit/semgrep p/django 白盒速达。
  4. FastAPI 信息泄露:生产 /openapi.json/docs/redoc 是完整攻击面地图;include_in_schema=False 的端点要靠前缀 fuzz。
  5. FastAPI 依赖漂移:Depends(get_token) 只是取 token,验签和授权是自己的事;extra="allow" 是 Pydantic 的隐形批量赋值;子应用挂载可绕过全局中间件。
  6. NestJS 守卫栈:global → controller → method,任一 method 漏挂 @UseGuards 即敞开;@Public() 过宽、Reflector 键名不匹配(roles vs role)默认放行。
  7. NestJS 多传输盲区:WebSocket gateway 与微服务 @MessagePattern 常无守卫;ValidationPipe 可能只配 HTTP;CacheInterceptor 不带身份 key = 跨用户缓存投毒。
  8. Next.js 中间件:路径规范化(双斜杠/点段)、x-middleware-subrequest、参数污染(中间件查首值、handler 用末值)是三大绕过面。
  9. Next.js 数据暴露:__NEXT_DATA__ 过度获取、RSC flight data、ISR 缓存边界、Server Action 鉴权依赖客户端状态、Edge vs Node 运行时分叉。
  10. 共性心法:框架「默认帮你挡的」(Django CSRF、模板自动转义)与「留给你配但你忘了的」(DRF 权限类、FastAPI 依赖验签、NestJS 守卫、Next.js 中间件)——后者才是专项渗透的命中点。

下一节,我们把镜头从应用框架转向第三方技术栈——Active Directory、Auth0、Firebase、Grafana/Prometheus、Supabase。这些服务的错误配置(RLS 配错、SPN 可烤、callback 过宽、observability 暴晒)是另一类「栈特有」的高危攻击面。


发布者: 作者: 灏天文库 转发
评论区 (0)
U