一个 SaaS 系统最容易被低估的部分,往往不是业务功能,而是登录系统。用户注册、密码登录、MFA、Cookie、Session、密码重置、设备管理、API Token、OAuth、日志审计,这些功能看起来彼此独立,实际上共同组成了账户安全边界。只要其中一个环节设计错误,攻击者就可能绕过其他防护。因此,一个成熟的 SaaS 登录系统不能简单理解为“密码加密以后再加一个验证码”,而应该从身份认证、会话生命周期、访问控制、异常检测和账户恢复几个层面整体设计。
密码首先要解决的是存储问题,而不是简单地“加密”。用户密码不应该以明文形式保存,也通常不应该使用 AES 之类的对称加密算法保存,因为数据库一旦泄露,能够取得密钥的攻击者就可能直接恢复密码。对于密码这类需要验证但不需要还原的数据,更合适的方案是使用专门设计的密码哈希算法,例如 Argon2id、bcrypt 或 scrypt。每个密码都应该使用独立的随机盐值,哈希参数也应该根据服务器性能和安全要求进行配置。现代系统还可以考虑密码哈希升级机制,当用户成功登录时,如果发现账户仍然使用较旧的哈希参数,可以在认证成功后重新计算并更新密码哈希。
密码传输则是另外一个问题。浏览器向 SaaS 服务提交密码时,应当通过 HTTPS 连接发送,生产环境一般使用 TLS 1.2 或更高版本,并关闭已经废弃或存在明显安全问题的协议和密码套件。TLS 的作用是保护客户端与服务器之间传输数据的机密性和完整性,而不是替代密码哈希。正常配置并正确验证服务器证书的 TLS,本身就是防御网络中间人攻击的重要机制。HSTS、正确的证书链、合理的 TLS 配置以及避免混合内容,都属于这一层的安全措施。
多因素认证则是在密码之外增加另一种身份验证因素。常见方案包括 TOTP、硬件安全密钥以及基于 WebAuthn 的 Passkey。TOTP 是基于时间的一次性密码,通过共享密钥和时间窗口计算验证码,通常采用 HMAC 算法生成短数字验证码。原文中把 TOTP 同时写成“基于事件的一次性密码”是不准确的,基于事件的一次性密码属于另一类 OTP 机制。
如果系统面向企业客户,MFA 的设计重点并不是简单地增加一个输入框,而是解决注册、绑定、验证、设备丢失和账户恢复整个生命周期。例如用户启用 MFA 后,应当保存经过适当保护的 MFA 密钥,同时提供一次性恢复代码。恢复代码应该具有足够的随机性,而且使用后立即失效。对于高价值企业账户,单纯依赖管理员通过邮件或者人工方式重置 MFA 也存在风险,因此管理员重置操作本身应该受到权限控制并留下不可抵赖的审计记录。
对于安全要求较高的新系统,还可以考虑 Passkey。与传统密码相比,WebAuthn 和 Passkey 可以利用公钥密码体系完成认证,服务器保存的是公钥而不是用户的登录秘密,认证过程也能够抵抗许多传统的钓鱼攻击。对于企业 SaaS,Passkey 并不一定需要完全取代密码,可以作为更强的认证方式逐步加入账户体系。
用户通过认证以后,系统还必须解决“这个用户接下来是谁”的问题,这就是会话管理。传统 Web SaaS 通常通过安全 Cookie 保存随机 Session ID,而不是把完整用户身份信息直接放进浏览器。Session ID 必须具有足够的随机性,不能使用连续数字、用户 ID、邮箱或其他可预测内容。
Session Cookie 应当根据应用架构设置 Secure、HttpOnly 和合理的 SameSite 属性。Secure 可以要求 Cookie 只通过 HTTPS 发送,HttpOnly 可以降低客户端脚本直接读取 Session Cookie 的风险,SameSite 则能够减少部分跨站请求带来的攻击面。对于涉及状态改变的请求,还应结合 CSRF 防护机制,不能认为设置了 Cookie 就自动解决了 CSRF 问题。
Session 的生命周期也不能简单规定成所有系统都必须五分钟或者十五分钟。企业后台、普通 SaaS 用户界面、金融操作和高风险管理后台的安全要求不同。比较合理的设计通常包括空闲超时、绝对生命周期以及高风险操作重新认证。例如用户长时间没有操作,可以让 Session 过期;即使用户持续活动,也可以要求经过一定时间重新认证。修改密码、改变 MFA 设置、添加管理员、修改付款信息等高价值操作,还可以要求重新验证身份。
Session ID 本身也不应该因为“安全”就机械地与用户 IP 地址绑定。移动网络、企业 NAT、VPN、代理服务器以及 IPv4 和 IPv6 网络变化都可能造成同一个用户的出口地址改变。如果系统发现 IP 变化就立即销毁 Session,很容易把正常用户踢出去。更合理的做法是把 IP、User-Agent、设备信息、登录地点、访问行为等作为风险信号之一,而不是单独把某个 IP 当成用户身份的永久证明。
对于 Session Token 是否需要加密存储,也应该根据具体架构判断。如果服务器使用随机的高熵 Session ID,数据库或者 Session Store 中通常没有必要保存可以恢复出原始 Token 的密钥材料。一个常见做法是服务器只保存 Token 的哈希值,客户端持有原始 Token。当客户端提交 Token 后,服务器对其进行哈希并进行查找。这样即使 Session 存储被读取,攻击者也不能直接拿数据库中的值当作有效 Session 使用。
JWT 则属于另一种设计思路。JWT 是一种令牌格式,并不等于 Session,也不是因为使用 JWT 就自动更加安全。JWT 可以携带声明并进行签名验证,但一旦已经签发的 Token 在有效期内被盗,服务器是否能够立即撤销它就成为一个实际问题。因此,是否使用 JWT 应该取决于系统架构,而不是因为它听起来更现代。对于很多传统 SaaS Web 应用,一个设计良好的服务端 Session 加安全 Cookie 反而更加直接。
如果采用 Access Token 和 Refresh Token 架构,则必须认真设计 Token 生命周期、刷新和撤销机制。Refresh Token 通常应该具有更长的生命周期,但风险也更高,因此可以采用轮换机制。每次刷新后发放新的 Refresh Token,并使旧 Token 失效,可以降低 Token 被复制后长期使用的风险。OAuth 2.0 是授权框架,不应该被简单理解为“登录 Token 的一种格式”;如果系统需要标准化的用户身份认证,还需要结合 OpenID Connect 等机制。
暴力破解和凭证填充攻击则需要另一套控制措施。登录接口不能无限接受密码尝试。常见方法包括按照账户、IP、设备和请求特征进行速率限制,并结合短时间窗口、逐渐增加等待时间以及风险检测。只按照 IP 限制并不可靠,因为攻击者可以使用大量代理地址;只按照账户限制也可能被攻击者利用来骚扰特定用户。因此生产环境通常需要多维度限制。
登录失败后也不能返回过于详细的信息。例如“这个邮箱不存在”和“密码错误”如果返回完全不同的提示,攻击者可以利用登录接口批量枚举有效账户。更合理的设计是尽量避免暴露账户是否存在,同时通过后端日志记录更加详细的信息供安全系统分析。
CAPTCHA 可以作为风险控制手段,但不应该成为所有用户每次登录都必须完成的固定步骤。对于大量自动化请求、异常登录模式、短时间失败次数明显增加等情况,可以逐步提高验证强度。现代系统还可以结合 IP 信誉、设备风险、异常地理位置、登录时间、历史行为以及已知泄露凭证信息进行风险评分。
密码重置系统同样属于登录系统的一部分,而且经常成为攻击者绕过正常认证流程的入口。“忘记密码”不能简单地发送一个包含用户 ID 的链接。重置链接应该使用高熵随机值、具有较短有效期,并且只能使用一次。服务器应该保存重置 Token 的安全表示,而不是直接保存可以用于重置账户的长期秘密。密码重置成功后,还应该考虑是否撤销现有 Session 和其他认证凭证。
账户恢复甚至可能比正常登录更加敏感。攻击者如果无法破解密码,却能够通过薄弱的恢复流程接管账户,前面的密码哈希、MFA 和 Session 安全措施都会失去意义。因此,企业 SaaS 应该特别保护邮箱变更、手机号变更、MFA 重置、恢复代码重新生成以及管理员代用户恢复账户等操作。
会话劫持防护还涉及 Session Fixation。用户完成登录以后,系统应该重新生成 Session ID,而不是继续使用登录前的 Session 标识。权限发生重大变化时,也可以进行 Session Rotation。用户主动退出登录后,服务器端应该让对应 Session 立即失效,而不是仅仅删除浏览器 Cookie。修改密码或者发现严重异常登录时,则可以进一步撤销该账户的其他活跃 Session。
安全审计日志是企业 SaaS 不可缺少的一层。至少应该记录登录成功、登录失败、MFA 成功和失败、密码修改、密码重置、邮箱变更、MFA 设置变化、新设备登录、Session 撤销、管理员身份操作以及权限变化等事件。日志中可以包含时间、账户标识、来源 IP、User-Agent、设备信息以及事件结果,但不应该把密码、完整 Session Token、Refresh Token 等敏感凭证直接写进日志。
日志保留多久不能简单规定所有系统统一六个月。具体期限应该根据业务需求、合规要求、客户合同以及安全调查需求确定。企业客户通常会要求更加完整的审计能力,因此 SaaS 平台还需要考虑日志完整性、访问权限、集中存储、检索效率以及告警机制。SIEM 可以进一步把认证日志与其他安全事件结合起来,用于发现账户接管、密码喷洒、异常管理员操作等攻击行为。
设备识别也需要谨慎处理。Canvas、WebGL 等浏览器指纹技术可以提供一定的风险信号,但它们并不是可靠的永久设备身份证明。浏览器升级、隐私保护功能、插件、系统变化以及用户主动清除数据,都可能导致指纹发生变化。同时,浏览器指纹涉及隐私问题,在面向加拿大、欧洲以及其他隐私监管环境的 SaaS 产品中,还需要考虑数据收集目的、透明度和相关合规要求。
因此,与其强行把 Session 永久绑定到一个所谓“设备指纹”,不如把设备信息作为风险判断的一部分。用户第一次从新设备登录,可以要求额外验证;已经验证过的设备可以获得较低风险评分;当设备、IP、登录地点和行为同时出现异常时,再要求重新认证。这种方式通常比简单的 IP 白名单或者浏览器指纹绑定更加实用。
API 安全还需要单独设计。SaaS 系统的登录安全不能只考虑网页。移动 App、前端 JavaScript、第三方集成以及内部服务都会调用 API。API 应该使用 HTTPS,并根据用途采用 Session Cookie、OAuth 2.0 Access Token、服务账户凭证或者其他合适的认证机制。对于高权限 API,还需要严格检查授权,而不能因为用户已经成功登录,就认为用户可以访问所有资源。
这也是 SaaS 与普通单用户网站的重要区别。认证只解决“你是谁”,授权解决的是“你可以做什么”。一个用户即使已经完成密码和 MFA 验证,也不应该因此获得其他租户的数据。多租户 SaaS 必须在服务端持续执行租户隔离和对象级授权检查,不能仅仅依靠前端隐藏菜单或者修改 URL 参数来限制访问。
例如一个请求访问某个客户订单时,服务器不能只检查“当前用户已经登录”,还必须检查这个用户是否属于对应租户,以及是否拥有访问这个订单的权限。对于管理员、财务人员、普通员工和 API 集成账户,还应该根据角色或者更细粒度的权限模型控制操作范围。大量 SaaS 数据泄露事件并不一定来自密码破解,而可能来自认证成功之后的授权漏洞。
登录系统还需要防御自动化攻击。攻击者可能使用泄露的用户名和密码进行 Credential Stuffing,也可能使用大量不同账户进行 Password Spraying。此时单纯增加密码复杂度并不能解决问题。系统需要结合速率限制、异常行为检测、泄露密码检测、MFA、设备风险以及账户保护机制降低成功率。
性能方面,也不能把“加密算法很快”简单等同于登录系统没有性能问题。对于正常 SaaS 登录流量,密码哈希通常才是认证过程中计算成本较高的环节之一,而这恰恰是安全设计的一部分。密码哈希不能为了追求吞吐量而配置得过于廉价,否则攻击者获得数据库后可以更快地进行离线破解。
Session Store 也可能成为大型 SaaS 的瓶颈。小规模系统可以直接使用数据库或者单机缓存,而大规模系统可能采用 Redis 等集中式 Session Store,并通过高可用和故障转移机制避免单点故障。这里需要根据 Session 数据量、访问频率、过期策略和故障恢复要求进行架构设计,而不是认为“用了 Redis 就安全”。
TOTP 本身的计算通常并不是 SaaS 登录性能的主要瓶颈。用户输入验证码后,服务器可以在本地完成验证,并根据允许的时间偏移处理客户端与服务器之间的小幅时钟差。把 TOTP 验证设计成必须经过一个额外远程服务的异步流程,反而可能增加系统复杂度和延迟。真正需要重点考虑的是 MFA 服务的可用性、密钥保护和恢复流程。
安全策略也应该具有动态调整能力。一个正常用户在熟悉的设备上从常用地点登录,系统没有必要每次都增加额外验证;如果账户突然出现异常设备、新地点、大量失败尝试或者高风险操作,则可以要求重新认证或者提高 MFA 强度。这种风险自适应认证能够在安全性和用户体验之间取得更合理的平衡。
不过,所谓“风险评分”也不能变成一个完全不可解释的黑盒。企业客户可能需要知道为什么某次登录被阻止,安全团队也需要能够从日志中还原事件。因此风险策略应该能够解释主要触发因素,并允许管理员查看和调整相关规则。
一个成熟的 SaaS 登录系统最终可以拆成几个相互配合的安全层。第一层是密码或 Passkey 等身份验证机制,第二层是 MFA 和风险认证,第三层是安全 Cookie 与 Session 生命周期管理,第四层是 CSRF、速率限制和自动化攻击防护,第五层是账户恢复与高风险操作重新认证,第六层是租户隔离和权限控制,第七层则是审计日志、告警和安全响应。
其中任何一层都不能独立承担全部责任。TLS 不能替代密码哈希,MFA 不能替代授权检查,Redis 不能替代 Session 生命周期设计,JWT 也不会自动解决 Token 撤销问题,浏览器指纹更不能成为设备身份的绝对依据。SaaS 登录系统真正困难的地方,不是堆积多少安全产品,而是让认证、会话、权限、恢复和审计形成一个完整的闭环。
当用户能够正常登录时,系统应该尽可能简单;当攻击者试图破解、劫持、枚举、接管或者横向访问其他租户时,系统则应该能够逐层提高防护强度。这样的设计既不会把所有正常用户都困在 CAPTCHA 和重复验证中,也不会因为某一个安全措施失效就让整个 SaaS 平台失去保护。
一个安全的 SaaS 登录系统需要哪些功能,从密码到会话管理逐项了解
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP