logo

GHSA-vp58-j275-797x better-auth

Package

Manager: npm
Name: better-auth
Vulnerable Version: >=0 <1.1.21

Severity

Level: Critical

CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N/E:U/RL:O/RC:C

CVSS v4.0: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

EPSS: N/A pctlN/A

Details

Better Auth allows bypassing the trustedOrigins Protection which leads to ATO ### Summary A bypass was found for **wildcard** or **absolute URLs** trustedOrigins configurations and opens the victims website to a **Open Redirect** vulnerability, where it can be used to steal the **reset password token** of a victims account by changing the "callbackURL" parameter value to a website owned by the attacker. ### Details #### Absolute URLs The issue here appears in the **middleware**, [specifically](https://github.com/better-auth/better-auth/blob/ddebd0358d74376ea64541512d0167dd4377f182/packages/better-auth/src/api/middlewares/origin-check.ts#L53). This protection is not sufficiente and it allows attackers to exploit a open redirect vulnerability, by using the payload `/\/example.com`. We can check this is a valid URL ( or it will be a valid URL because the URL parser fix it for us ), by checking the image bellow: ![image](https://github.com/user-attachments/assets/d192f06d-358d-4612-97d9-cab89ba55b06) ```typescript // trustedOrigins = [ "https://example.com" ] validateURL("https://attacker.com", "callbackURL") // ❌ APIError, No Redirect validateURL("/\/attacker.com", "callbackURL") // ✅ Redirect to http://attacker.com ``` #### Regex The issue here is because the regex is not strong enough `[^/\\]*?\.example\.com[/\\]*?` ( this is the regex it will be created if we have a wildcard as the trustedOrigins config ), but we can bypass by using a payload like: ```text // trustedOrigins = [ "*.example.com" ] ┌──────────────────┐ ┌────────────────┐ ┌─────────────────┐ │ None of [ "/\" ] │ ────▶ │ ".example.com" │ ────▶ │ One of [ "/\" ] │ └──────────────────┘ └────────────────┘ └─────────────────┘ demo .example.com / ✅ Redirect to https://example.com demo .attacker.com / ❌ APIError, no redirect http:attacker.com? .example.com / ✅ Redirect to http://attacker.com ```` This works because **:** and **?** are special chars in a URL, so when the URL parser sees, **http:** it will fix our happily fix our URL to http://attacker.com? and make `.example.com` as parameter, thus, bypassing this check. ### PoC We can PoC the open redirect by using the `demo.better-auth.com`. If we access the URL bellow, we are redirected to example.com: - https://demo.better-auth.com/api/auth/reset-password/x?callbackURL=/\/example.com ### Impact Every single website using the **better-auth** library, is vulnerable to un-auth open redirect and more importantilly, vulnerable to potential one click account take over vulnerability, as the attacker can send the victim a email to reset their account while changing the "redirectTo" parameter [here](https://demo.better-auth.com/forget-password), and when the victim clicks on the link, the reset token is sent to the attackers website, which then a attacker could use that token to reset the password of the victims account.

Metadata

Created: 2025-02-24T20:49:50Z
Modified: 2025-03-03T13:44:59Z
Source: https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/02/GHSA-vp58-j275-797x/GHSA-vp58-j275-797x.json
CWE IDs: ["CWE-601"]
Alternative ID: N/A
Finding: F007
Auto approve: 1