跳到正文
>_ITDITDWeb 安全平台

安全指南

加了登录就以为安全了吗 — 认证与授权的区别

认证(你是谁)与授权(你可以做什么)是两回事。只加了登录、却没有按所有者(user_id)收窄数据,就会出现「登录 = 看到全部数据」的事故。本文讲解成因与防御。

发布于 2026-06-30 更新于 2026-07-03 2 分钟阅读

「我加了登录功能,所以现在已经受保护了」——这是一个危险的想当然。实际上,登录(认证)和权限(授权)是两回事,一旦把这里弄混,就会发生只要登录,所有人都能看到包括他人在内的全部数据的事故。这里不写攻击步骤,只讲成因与防御。

认证与授权是两回事

它们很容易被混淆,但角色完全不同。

只有认证(常见的误解)

  • 觉得「能登录 = 安全」
  • 把登录后的数据读取当成对所有人都一样
  • 结果:只要登录,所有人都能到达全部数据

认证 + 授权(本应如此)

  • 用认证确认「你是谁」
  • 用授权限定到「这个人可以触碰的数据」
  • 数据读取始终按本人所有的范围收窄

认证是「入口处的身份核验」,授权是「控制可以进入哪些房间」。登录功能只保证前者。「谁可以触碰哪些数据」需要你另外编写。

authn
在入口确认「你是谁」(登录)
authz
按每个房间控制「谁可以进入」(按所有者收窄)
no authz
进来了 = 所有房间都能进 = 登录的所有人都能看到全部数据
认证只在门口核验身份。若没有每个房间的钥匙(授权),进来的人就能进入所有房间。

「看到全部数据」在真实应用中是怎么发生的

在实战中,同一个漏洞在多个彼此独立、各自自建的系统里反复出现。无论是个人用的任务/笔记管理应用,还是小规模的商品・订单管理系统(带有外部 API 集成),成因都是同样两个缺陷的叠加

1

① 注册是开放的(而且有两条入口)

认证脚手架(例如 Laravel 的 Breeze/Jetstream 之类的东西)往往默认就把注册页面设为公开。而当注册路由在 UI 库一侧和认证包一侧重复存在时,堵住一处后 /register 依然留着。知道 URL 的陌生人就能注册。

2

② 有认证但没有授权(缺少所有者收窄)

数据表没有所有者列(user_id),或者列表・读取・更新・删除的查询没有收窄到当前用户。于是「登录 = 可访问全部数据」。如果应用在注册后立即自动登录,陌生人一注册就会落到他人的数据列表上。

3

结果:认证 ≠ 授权 的事故

入口(登录)是有的,但房间的钥匙(授权)没有。因为陌生人表现得像「一个正常登录的用户」,几乎连未授权访问的痕迹都不会留下。

越是牵涉业务数据,爆炸半径就越大(客户资料、订单、集成用的 API 密钥都可能受波及)。而且用同样方式搭建的另一套系统,很可能也存在同样的漏洞。

如何防御

1

数据必须按所有者收窄

把每一次读写都限定为「当前登录用户自己的那些行」。通过 ORM 的全局 scope 或授权策略(policy/gate),对读取/更新/删除的全部操作强制加上所有者条件。如果表里没有所有者列,先从那里重新设计。

2

关闭不需要的注册——并怀疑入口重复

在个人/内部应用上停用注册。要通过 HTTP 实测 /register 之类确实返回 404,并检查 UI 库和认证包两侧的注册路由

3

对管理面做纵深防御

对于内部/管理用途,不要只靠认证——叠加 IP 限制、Basic 认证等。就算一道墙被攻破,下一道也能拦住。

4

在事故*发生之前*就备好审计与访问日志

如果没有「谁、在何时、从哪个 IP、做了什么」,事后就无法还原「什么被看到了」。至少要保留登录成败的审计日志,并保留/轮转 Web 访问日志。

5

检测新注册与异常

这次的核心教训是「很长时间都没被察觉」。加入能尽早察觉的机制——新用户注册的通知、定期的用户/数据盘点。没有检测,漏洞就会一直静静地开着。

本站的观点:库只保证到『你是谁』为止

认证库替你操心的只到「你是谁」为止,再往后就没有了。「这个人可以做什么」——除非作为设计者的你亲手写出来,否则它并不存在。而且——在一套系统中发现的结构性缺陷,很可能也存在于用同样方式搭建的其他系统里。不要修好一件就收手,要横向排查所有同类结构的搭建。当你无法判断某样东西是否被读取过时,正确的姿态是把它当作已被读取,并对暴露的秘密进行失效/轮换。

接下来阅读

出处

FAQ

Q认证(Authentication)与授权(Authorization)有什么区别?
A

认证是确认『你是谁』(登录)。授权是决定『这个人可以做什么』(权限)。打个比方,认证是在大楼入口做身份核验,授权则是控制『这个人可以进入哪些房间』。只加了登录功能,只实现了认证,而授权(谁可以触碰哪些数据)需要你另外编写。把两者混为一谈,就会落到『只要登录,就能看到全部数据』的地步。

Q明明有登录功能,为什么所有数据都能被看到?
A

因为取数据的查询没有收窄到『只取当前登录本人自己的那些行』。只要在列表、读取、更新、删除中的任何一处漏掉了所有者(user_id)条件,一旦登录通过,包括他人在内的全部行都会被返回。这是一个与是否存在认证无关的设计漏洞,正是 OWASP 排名第一的 Broken Access Control(访问控制缺陷)的典型。

Q如果是个人工具或内部应用,注册一直开着也没关系吧?
A

很危险。许多认证脚手架默认就把注册(如 /register)设为公开。只要知道 URL,陌生人就能注册;一旦没有授权,就会直接到达里面的数据。而且注册入口有时是重复的(UI 库和认证包各有一套),只堵住一处并不能关闭它。请立即停用不需要的注册,并在管理面叠加 IP 限制等纵深防御。