@better-auth/core 1.6.13 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context/global.mjs +1 -1
- package/dist/instrumentation/tracer.mjs +1 -1
- package/dist/utils/redirect-uri.d.mts +1 -0
- package/dist/utils/redirect-uri.mjs +9 -2
- package/dist/utils/url.mjs +7 -2
- package/package.json +1 -1
- package/src/utils/redirect-uri.ts +12 -3
- package/src/utils/url.ts +5 -2
package/dist/context/global.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { ATTR_HTTP_RESPONSE_STATUS_CODE } from "./attributes.mjs";
|
|
|
2
2
|
import { getOpenTelemetryAPI } from "./api.mjs";
|
|
3
3
|
//#region src/instrumentation/tracer.ts
|
|
4
4
|
const INSTRUMENTATION_SCOPE = "better-auth";
|
|
5
|
-
const INSTRUMENTATION_VERSION = "1.6.
|
|
5
|
+
const INSTRUMENTATION_VERSION = "1.6.14";
|
|
6
6
|
/**
|
|
7
7
|
* Better-auth uses `throw ctx.redirect(url)` for flow control (e.g. OAuth
|
|
8
8
|
* callbacks). These are APIErrors with 3xx status codes and should not be
|
|
@@ -6,6 +6,7 @@ import * as z from "zod";
|
|
|
6
6
|
* server stores and later hands back to a browser.
|
|
7
7
|
*
|
|
8
8
|
* - Rejects dangerous schemes (`javascript:`, `data:`, `vbscript:`).
|
|
9
|
+
* - Rejects URIs with a fragment component (`#...`) per RFC 6749 §3.1.2.
|
|
9
10
|
* - Requires HTTPS, except for loopback hosts (`127.0.0.0/8`, `[::1]`,
|
|
10
11
|
* `*.localhost` per RFC 6761), where HTTP is allowed for local development.
|
|
11
12
|
* - Allows custom schemes for mobile apps (e.g. `myapp://callback`).
|
|
@@ -7,6 +7,7 @@ import * as z from "zod";
|
|
|
7
7
|
* server stores and later hands back to a browser.
|
|
8
8
|
*
|
|
9
9
|
* - Rejects dangerous schemes (`javascript:`, `data:`, `vbscript:`).
|
|
10
|
+
* - Rejects URIs with a fragment component (`#...`) per RFC 6749 §3.1.2.
|
|
10
11
|
* - Requires HTTPS, except for loopback hosts (`127.0.0.0/8`, `[::1]`,
|
|
11
12
|
* `*.localhost` per RFC 6761), where HTTP is allowed for local development.
|
|
12
13
|
* - Allows custom schemes for mobile apps (e.g. `myapp://callback`).
|
|
@@ -16,7 +17,10 @@ import * as z from "zod";
|
|
|
16
17
|
* rather than re-implementing the scheme policy per plugin.
|
|
17
18
|
*/
|
|
18
19
|
const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
19
|
-
|
|
20
|
+
let u;
|
|
21
|
+
try {
|
|
22
|
+
u = new URL(val);
|
|
23
|
+
} catch {
|
|
20
24
|
ctx.addIssue({
|
|
21
25
|
code: "custom",
|
|
22
26
|
message: "URL must be parseable",
|
|
@@ -24,7 +28,6 @@ const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
|
24
28
|
});
|
|
25
29
|
return z.NEVER;
|
|
26
30
|
}
|
|
27
|
-
const u = new URL(val);
|
|
28
31
|
if (DANGEROUS_URL_SCHEMES.includes(u.protocol)) {
|
|
29
32
|
ctx.addIssue({
|
|
30
33
|
code: "custom",
|
|
@@ -32,6 +35,10 @@ const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
|
32
35
|
});
|
|
33
36
|
return;
|
|
34
37
|
}
|
|
38
|
+
if (val.includes("#")) ctx.addIssue({
|
|
39
|
+
code: "custom",
|
|
40
|
+
message: "Redirect URI must not contain a fragment component"
|
|
41
|
+
});
|
|
35
42
|
if (u.protocol === "http:" && !isLoopbackHost(u.host)) ctx.addIssue({
|
|
36
43
|
code: "custom",
|
|
37
44
|
message: "Redirect URI must use HTTPS (HTTP allowed only for loopback hosts)"
|
package/dist/utils/url.mjs
CHANGED
|
@@ -48,8 +48,13 @@ const DANGEROUS_URL_SCHEMES = [
|
|
|
48
48
|
* execution schemes without rejecting relative paths or mobile deep links.
|
|
49
49
|
*/
|
|
50
50
|
function isSafeUrlScheme(value) {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = new URL(value);
|
|
54
|
+
} catch {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return !DANGEROUS_URL_SCHEMES.includes(parsed.protocol);
|
|
53
58
|
}
|
|
54
59
|
//#endregion
|
|
55
60
|
export { DANGEROUS_URL_SCHEMES, isSafeUrlScheme, normalizePathname };
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import { DANGEROUS_URL_SCHEMES } from "./url";
|
|
|
7
7
|
* server stores and later hands back to a browser.
|
|
8
8
|
*
|
|
9
9
|
* - Rejects dangerous schemes (`javascript:`, `data:`, `vbscript:`).
|
|
10
|
+
* - Rejects URIs with a fragment component (`#...`) per RFC 6749 §3.1.2.
|
|
10
11
|
* - Requires HTTPS, except for loopback hosts (`127.0.0.0/8`, `[::1]`,
|
|
11
12
|
* `*.localhost` per RFC 6761), where HTTP is allowed for local development.
|
|
12
13
|
* - Allows custom schemes for mobile apps (e.g. `myapp://callback`).
|
|
@@ -16,7 +17,10 @@ import { DANGEROUS_URL_SCHEMES } from "./url";
|
|
|
16
17
|
* rather than re-implementing the scheme policy per plugin.
|
|
17
18
|
*/
|
|
18
19
|
export const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
19
|
-
|
|
20
|
+
let u: URL;
|
|
21
|
+
try {
|
|
22
|
+
u = new URL(val);
|
|
23
|
+
} catch {
|
|
20
24
|
ctx.addIssue({
|
|
21
25
|
code: "custom",
|
|
22
26
|
message: "URL must be parseable",
|
|
@@ -25,8 +29,6 @@ export const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
|
25
29
|
return z.NEVER;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
const u = new URL(val);
|
|
29
|
-
|
|
30
32
|
if (DANGEROUS_URL_SCHEMES.includes(u.protocol)) {
|
|
31
33
|
ctx.addIssue({
|
|
32
34
|
code: "custom",
|
|
@@ -35,6 +37,13 @@ export const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
if (val.includes("#")) {
|
|
41
|
+
ctx.addIssue({
|
|
42
|
+
code: "custom",
|
|
43
|
+
message: "Redirect URI must not contain a fragment component",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
if (u.protocol === "http:" && !isLoopbackHost(u.host)) {
|
|
39
48
|
ctx.addIssue({
|
|
40
49
|
code: "custom",
|
package/src/utils/url.ts
CHANGED
|
@@ -60,9 +60,12 @@ export const DANGEROUS_URL_SCHEMES = ["javascript:", "data:", "vbscript:"];
|
|
|
60
60
|
* execution schemes without rejecting relative paths or mobile deep links.
|
|
61
61
|
*/
|
|
62
62
|
export function isSafeUrlScheme(value: string): boolean {
|
|
63
|
-
|
|
63
|
+
let parsed: URL;
|
|
64
|
+
try {
|
|
65
|
+
parsed = new URL(value);
|
|
66
|
+
} catch {
|
|
64
67
|
// Relative URLs carry no scheme to abuse.
|
|
65
68
|
return true;
|
|
66
69
|
}
|
|
67
|
-
return !DANGEROUS_URL_SCHEMES.includes(
|
|
70
|
+
return !DANGEROUS_URL_SCHEMES.includes(parsed.protocol);
|
|
68
71
|
}
|