安全性

Better Auth 的安全功能。

本页面包含有关 Better Auth 安全功能的信息。

密码哈希

Better Auth 默认使用 scrypt 算法进行密码哈希。该算法设计为内存硬和 CPU 密集型,能够抵抗暴力破解攻击。您可以通过配置中的 password 选项自定义密码哈希函数。该选项应包含用于哈希密码的 hash 函数和用于验证密码的 verify 函数。

秘钥轮换

Better Auth 支持对 BETTER_AUTH_SECRET 进行非破坏性的轮换。当您通过 secrets 选项或 BETTER_AUTH_SECRETS 环境变量配置版本化秘钥时,所有新的加密数据都会包含一个密钥版本标识符。解密时会直接通过版本号查找密钥——无需尝试性解密。

轮换前使用旧秘钥加密的遗留数据(裸十六进制格式)仍可通过原始的 BETTER_AUTH_SECRET 作为回退进行解密。无需数据库迁移或停机。数据在下一次写入时会懒惰地使用当前密钥重新加密。

配置细节请参见 secrets 选项

会话管理

会话过期

Better Auth 使用安全的会话管理来保护用户数据。会话存储在数据库或次级存储(如果配置了)中,以防止未经授权的访问。默认情况下,会话在 7 天后过期,您可以在配置中自定义这个值。此外,每次使用会话时,如果达到 updateAge 阈值(默认 1 天),过期时间将被延长。

会话撤销

Better Auth 允许您撤销会话以增强安全性。当会话被撤销后,用户会退出登录,无法再访问应用。已登录用户还可以撤销自己的会话,以便从不同设备或浏览器登出。

更多详情请参见 会话管理

CSRF 保护

Better Auth 包含多重防护措施以防止跨站请求伪造(CSRF)攻击:

  1. 避免简单请求
    详情请参见 避免简单请求。Better Auth 只允许带有非简单头部或 Content-Typeapplication/json 的请求。

  2. Origin 验证
    每个请求的 Origin 头都会校验,确保来自您的应用或其他明确可信来源。不受信任来源的请求将被拒绝。默认情况下,Better Auth 信任应用的基础 URL,您也可以通过 trustedOrigins 配置额外的可信来源。

  3. 安全 Cookie 设置
    会话 Cookie 默认使用 SameSite=Lax 属性,防止浏览器随大多数跨站请求发送 Cookie。您可以通过 defaultCookieAttributes 选项覆盖此行为。

  4. 首登录 CSRF 的 Fetch Metadata 保护
    Better Auth 还利用 Fetch Metadata 头部Sec-Fetch-SiteSec-Fetch-ModeSec-Fetch-Dest)对首登录场景提供额外防护,此时客户端还没有任何 Cookie。

    此保护适用于登录和注册的邮件路由,它们接受表单提交(简单请求),以支持渐进式增强模式。

    当接收到没有任何 Cookie 的登录或注册请求时:

    • 如果浏览器标示这是一次跨站导航(例如:Sec-Fetch-Site: cross-siteSec-Fetch-Mode: navigate),Better Auth 会将该请求阻止,视为潜在的登录 CSRF 攻击。

    • 如果请求是同源同站,Better Auth 仍会根据配置的 trustedOrigins 验证 Origin/Referer,使用现有的源验证逻辑。

    • 如果客户端不发送 Fetch Metadata 头(老旧浏览器、部分移动 WebView、非浏览器客户端),Better Auth 会回退到之前的行为,只有在存在 Cookie 时才进行源验证,保持向后兼容。

    该机制允许现代浏览器在无需 CSRF 令牌或客户端 JavaScript 的情况下,获得更强的首登录 CSRF 防护,并与渐进式增强模式无缝配合。

    非浏览器 HTTP 客户端(移动应用、服务器间调用)应在包含 Cookie 的请求中正确设置 OriginReferer 头。这可确保无论是否支持 Fetch Metadata 都能正确进行 CSRF 验证。

  5. GET 请求无状态变更(带额外防护)
    认为 GET 请求是只读的,不应用于更改应用状态。必须在 GET 请求中执行状态变更的情况,如 OAuth 回调时,Better Auth 会采取额外安全措施,包括校验 noncestate 参数以确保请求的真实性。

禁用安全检查

Better Auth 提供了两个单独选项用于禁用安全检查,分别控制不同的安全方面:

disableCSRFCheck

禁用所有 CSRF 保护,包括:

  • 在存在 Cookie 时校验 Origin 头
  • Fetch Metadata 检查(Sec-Fetch-SiteSec-Fetch-ModeSec-Fetch-Dest
  • 首登录场景中的跨站导航阻止
{
  advanced: {
    disableCSRFCheck: true
  }
}

禁用 CSRF 检查允许任意来源的请求携带 Cookies,并以用户身份执行操作。这会使您的应用暴露于 CSRF 攻击风险。

disableOriginCheck

禁用针对 trustedOriginsURL 验证,包括:

  • callbackURL 验证
  • redirectTo 验证
  • errorCallbackURL 验证
  • newUserCallbackURL 验证
{
  advanced: {
    disableOriginCheck: true
  }
}

禁用源检查允许任何 URL 用于重定向和回调。这会使您的应用暴露于开放重定向漏洞。

为保持向后兼容,设置 disableOriginCheck: true 也会禁用 CSRF 保护。如果您只想禁用 URL 验证而不影响 CSRF 保护,目前尚不可行——启用此选项时,两者都会被一起禁用。

总结

选项禁用的功能
disableCSRFCheck仅禁用 CSRF 保护(Origin 头验证、Fetch Metadata 检查)
disableOriginCheck禁用 URL 验证和 CSRF 保护(用于向后兼容)

OAuth 状态和 PKCE

为保障 OAuth 流程安全,Better Auth 将 OAuth 状态和 PKCE(Proof Key for Code Exchange)存储在数据库中。状态用于防止 CSRF 攻击,PKCE 防止代码注入攻击。OAuth 流程完成后,这些值将从数据库中移除。

Cookies

Better Auth 默认当基础 URL 使用 https 时分配安全 Cookie。这些安全 Cookie 会加密且只通过安全连接发送,增加一层保护。默认设置 sameSite 属性为 lax,防止跨站请求伪造攻击,并启用 httpOnly,防止客户端 JavaScript 访问 Cookie。

对于跨子域 Cookie,您可以在配置中设置 crossSubDomainCookies 选项。该选项允许跨子域共享 Cookie,实现不同子域间的无缝认证。

自定义 Cookies

您可以自定义 Cookie 名称,以减小指纹识别攻击风险,并根据需要设置具体的 Cookie 选项以获得更细粒度的控制。详情请参见 Cookie 选项

插件也可以设置自定义 Cookie 选项,以满足特定安全需求。如果在非浏览器环境中使用 Better Auth,插件也提供了安全管理 Cookie 的方法。

速率限制

Better Auth 内置了速率限制功能以防御暴力破解攻击。速率限制默认应用于所有路由,对潜在风险较高的特定路由会实施更严格的限制。

IP 地址头部

Better Auth 使用客户端 IP 地址进行速率限制和安全监控。默认情况下,它从标准的 X-Forwarded-For 头读取 IP 地址。但您可以配置特定的受信任头部,以确保准确的 IP 地址检测并防止 IP 欺骗攻击。

您可以在 Better Auth 配置中设置 IP 地址头部:

{
  advanced: {
    ipAddress: {
      ipAddressHeaders: ['cf-connecting-ip'] // 或其它自定义头部
    }
  }
}

这确保 Better Auth 只接受来自您可信代理的头部中的 IP 地址,使攻击者更难通过伪造头部绕过速率限制或其它基于 IP 的安全措施。

重要提示

  • 设置自定义 IP 地址头时,请确保您的代理或负载均衡器正确配置了该头,并且无法被终端用户直接设置。
  • 在开发或测试环境中,如果无法从头部获取 IP,则使用 127.0.0.1 作为回退。

受信任代理头

如果您的应用运行在反向代理或负载均衡器后,Better Auth 可以从入站请求的 X-Forwarded-HostX-Forwarded-Proto 头推断基础 URL。这在应用可通过多个域名(例如 example.comapp.example.dev)访问,且您不想在配置中硬编码单一 baseURL 时非常实用。

启用 trustedProxyHeaders 且配置中(或环境变量中)未设置 baseURL 时,Better Auth 会在每个请求中使用转发头构建基础 URL。这意味着 OAuth 回调、邮件验证链接和重定向会自动使用用户加载应用时的域名。

{
  advanced: {
    trustedProxyHeaders: true
  }
}

仅当您信任到达应用的代理头时启用此选项。您的反向代理或负载均衡器必须正确设置 X-Forwarded-HostX-Forwarded-Proto,且终端用户不能直接设置这些头。否则,未授权客户端可能伪造这些头,从而操控重定向和回调 URL。

启用后,基础 URL 解析优先级如下:

  1. 配置中的静态 baseURL(如果设置,代理头会被忽略)
  2. 环境变量(BETTER_AUTH_URLNEXT_PUBLIC_BETTER_AUTH_URL 等)
  3. trustedProxyHeaderstrue 时,使用 X-Forwarded-Host + X-Forwarded-Proto
  4. 请求 URL 源作为最终回退

如果您从多个经过批准的域提供应用,通常应:

  • 省略配置中的 baseURL,使其基于代理头按照请求动态推断
  • trustedOrigins 设为您批准域名的白名单(见下文)
  • 保持 crossSubDomainCookies 未启用——默认 Cookie 仅限于主机,每个域拥有独立会话

受信任来源

受信任来源可以防止 CSRF 攻击并阻止开放重定向。您可以在 trustedOrigins 配置选项中设置受信任来源列表。不在该列表中的请求来源会被自动阻止。

基本用法

最基本的用法是指定精确的来源:

{
  trustedOrigins: [
    "https://example.com",
    "https://app.example.com",
    "http://localhost:3000"
  ]
}

通配符来源

Better Auth 支持受信任来源中的通配符模式,允许通过单条规则信任多个子域:

{
  trustedOrigins: [
    "*.example.com",             // 信任 example.com 的所有子域(任意协议)
    "https://*.example.com",     // 仅信任 example.com 的 HTTPS 子域
    "http://*.dev.example.com"   // 信任 dev.example.com 的所有 HTTP 子域
  ]
}

特定协议通配符

当使用带协议前缀的通配符(如 https://)时:

  • 协议必须完全匹配
  • 域名中 * 可匹配任意子域
  • 协议不同的请求即使域名匹配也会被拒绝

协议无关通配符

当使用无协议前缀的通配符(如 *.example.com)时:

  • 允许任意协议(http、https 等)
  • 域名必须匹配通配符模式

自定义协议

受信任来源还支持移动应用和浏览器扩展的自定义协议:

{
  trustedOrigins: [
    "myapp://",                               // 移动应用协议
    "chrome-extension://YOUR_EXTENSION_ID",  // 浏览器扩展
    "exp://**",                               // 信任所有 Expo 开发 URL
    "exp://10.0.0.*:*/**",                    // 信任 IP 范围 10.0.0.x 及任意端口
  ]
}

动态来源列表

您也可以通过函数动态设置受信任来源列表:

{
  trustedOrigins: async (request) => {
    const trustedOrigins = await queryTrustedDomains();
    return trustedOrigins;
  }
}

重要:该函数会对每个传入请求调用,若动态获取受信任域列表,请注意性能和频率。

邮箱枚举保护

Better Auth 在注册和更改邮箱端点防止邮箱枚举。当启用 requireEmailVerificationautoSignIn 设置为 false 时,注册端点对已注册和未注册邮箱返回相同的 200 响应,遵循 OWASP 认证最佳实践。通过模拟密码哈希处理重复注册请求以减缓时间攻击。

配置细节请参见 邮箱和密码 — 邮箱枚举保护

安全漏洞报告

如果您发现 Better Auth 的安全漏洞,请通过 security@better-auth.com 向我们报告。我们将及时处理所有报告,并对经验证的漏洞发现予以鸣谢。