[GH-ISSUE #4780] Preserve full callbackURL when sending verification emails #18693

Closed
opened 2026-04-15 17:18:04 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @Jay-Ohhh on GitHub (Sep 20, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4780

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Currently, when the frontend sends a callbackURL containing query parameters (e.g., http://localhost:3000/?a=1&b=2) to the backend, the frontend correctly encodes it using encodeURIComponent. However, the backend decodes this callbackURL before including it in the verification email link.

As a result, the email link ends up splitting the callbackURL at the & character, causing the second query parameter (b=2) to be treated as a separate query parameter of the verification endpoint, rather than part of the callbackURL.

  1. Frontend encodes a URL with multiple query parameters:
    callbackURL: encodeURIComponent('http://localhost:3000/?a=1&b=2')

  2. Backend decodes this value and constructs the email link:
    http://localhost:3000/api/auth/verify-email?token=...&callbackURL=http://localhost:3000/?a=1&b=2

Image Image Image

Current vs. Expected behavior

Expected behavior / desired fix:

The backend should not decode the callbackURL when constructing the email link.

The link in the email should preserve the fully encoded callbackURL, e.g.:

What version of Better Auth are you using?

1.3.7

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.2.0: Fri Dec  6 18:51:28 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T8112",
    "release": "24.2.0",
    "cpuCount": 8,
    "cpuModel": "Apple M2",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.24 GB"
  },
  "node": {
    "version": "v22.19.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "10.9.3"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "Unknown",
    "config": null,
    "error": "ENOENT: no such file or directory, open 'package.json'"
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @Jay-Ohhh on GitHub (Sep 20, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4780 ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce Currently, when the frontend sends a callbackURL containing query parameters `(e.g., http://localhost:3000/?a=1&b=2) `to the backend, the frontend correctly encodes it using encodeURIComponent. However, the backend decodes this callbackURL before including it in the verification email link. As a result, the email link ends up splitting the callbackURL at the & character, causing the second query parameter (b=2) to be treated as a separate query parameter of the verification endpoint, rather than part of the callbackURL. 1. Frontend encodes a URL with multiple query parameters: `callbackURL: encodeURIComponent('http://localhost:3000/?a=1&b=2')` 2. Backend decodes this value and constructs the email link: `http://localhost:3000/api/auth/verify-email?token=...&callbackURL=http://localhost:3000/?a=1&b=2` <img width="1753" height="65" alt="Image" src="https://github.com/user-attachments/assets/78ace0b1-9fc1-4cc8-acd5-8782c405c3bb" /> <img width="975" height="162" alt="Image" src="https://github.com/user-attachments/assets/4ef2ae89-822a-4699-bfbf-a510698d75a5" /> <img width="948" height="169" alt="Image" src="https://github.com/user-attachments/assets/ebe47f86-98df-4789-91a9-95a3b9470ea5" /> ### Current vs. Expected behavior Expected behavior / desired fix: The backend should not decode the callbackURL when constructing the email link. The link in the email should preserve the fully encoded callbackURL, e.g.: ### What version of Better Auth are you using? 1.3.7 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.2.0: Fri Dec 6 18:51:28 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T8112", "release": "24.2.0", "cpuCount": 8, "cpuModel": "Apple M2", "totalMemory": "16.00 GB", "freeMemory": "0.24 GB" }, "node": { "version": "v22.19.0", "env": "development" }, "packageManager": { "name": "npm", "version": "10.9.3" }, "frameworks": null, "databases": null, "betterAuth": { "version": "Unknown", "config": null, "error": "ENOENT: no such file or directory, open 'package.json'" } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-15 17:18:04 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 20, 2025):

Hi @Jay-Ohhh! I'm Dosu and I’m helping the better-auth team.

This is a known bug in Better Auth v1.3.7 and earlier: the backend decodes the callbackURL before redirecting, which causes issues like splitting at '&' and breaking query parameters in verification email links. The fix for this was merged recently (PR #3863), but it is not included in v1.3.7—you'll need to upgrade to a newer version once it's released to get the fix.

Until then, workarounds include double-encoding the callbackURL before passing it to the backend (and decoding twice on the frontend), or manually parsing parameters on the frontend to handle spaces and splitting issues. There is no config option to change this behavior in your current version. This issue is absolutely suited for GitHub as a bug report for affected versions and as a feature/fix request if not yet released in your version. For more context and workarounds, see related issues: #3812, #2592, and #849.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3314639363 --> @dosubot[bot] commented on GitHub (Sep 20, 2025): <!-- Greeting --> Hi @Jay-Ohhh! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known bug in Better Auth v1.3.7 and earlier: the backend decodes the callbackURL before redirecting, which causes issues like splitting at '&' and breaking query parameters in verification email links. The fix for this was merged recently ([PR #3863](https://github.com/better-auth/better-auth/pull/3863)), but it is not included in v1.3.7—you'll need to upgrade to a newer version once it's released to get the fix. Until then, workarounds include double-encoding the callbackURL before passing it to the backend (and decoding twice on the frontend), or manually parsing parameters on the frontend to handle spaces and splitting issues. There is no config option to change this behavior in your current version. This issue is absolutely suited for GitHub as a bug report for affected versions and as a feature/fix request if not yet released in your version. For more context and workarounds, see related issues: [#3812](https://github.com/better-auth/better-auth/issues/3812), [#2592](https://github.com/better-auth/better-auth/issues/2592), and [#849](https://github.com/better-auth/better-auth/issues/849). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/0e99e95d-2834-4466-b028-9bd335059365?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4780)
Author
Owner

@Jay-Ohhh commented on GitHub (Sep 20, 2025):

@dosubot When do you plan to release an updated package that includes this fix?

<!-- gh-comment-id:3314644466 --> @Jay-Ohhh commented on GitHub (Sep 20, 2025): @dosubot When do you plan to release an updated package that includes this fix?
Author
Owner

@dosubot[bot] commented on GitHub (Sep 20, 2025):

The fix for preserving the full encoded callbackURL in verification emails was merged recently but hasn't been included in a stable release yet. There’s no official release date announced for the next package with this fix. However, maintainers have confirmed that it’s already available in the latest beta version and will be included in upcoming releases—so you can use the beta if you need the fix right away. Recent release activity (v1.3.10 and v1.3.11) suggests the next stable release should arrive soon, but for now, keep an eye on the repo for updates or subscribe to release notifications for the most current info [maintainer comment] [PR #3863] [v1.3.11 release].

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3314646271 --> @dosubot[bot] commented on GitHub (Sep 20, 2025): <!-- Answer --> The fix for preserving the full encoded callbackURL in verification emails was merged recently but hasn't been included in a stable release yet. There’s no official release date announced for the next package with this fix. However, maintainers have confirmed that it’s already available in the latest beta version and will be included in upcoming releases—so you can use the beta if you need the fix right away. Recent release activity (v1.3.10 and v1.3.11) suggests the next stable release should arrive soon, but for now, keep an eye on the repo for updates or subscribe to release notifications for the most current info [[maintainer comment](https://github.com/better-auth/better-auth/issues/2674#issuecomment-2917842427)] [[PR #3863](https://github.com/better-auth/better-auth/pull/3863)] [[v1.3.11 release](https://github.com/better-auth/better-auth/pull/4688)]. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/b9d44aa4-52b1-40cc-b8e2-59ba78361014?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4780)
Author
Owner

@dvanmali commented on GitHub (Sep 22, 2025):

@himself65 this can be closed with #3863

<!-- gh-comment-id:3320156375 --> @dvanmali commented on GitHub (Sep 22, 2025): @himself65 this can be closed with #3863
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18693