browserclaw 0.3.4 → 0.3.6
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/index.cjs +10 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -6
- package/dist/index.d.ts +17 -6
- package/dist/index.js +10 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -9,10 +9,19 @@ interface FrameEvalResult {
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Policy for controlling which URLs browser navigation is allowed to reach.
|
|
12
|
-
*
|
|
12
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
13
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
13
14
|
*/
|
|
14
15
|
interface SsrfPolicy {
|
|
15
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Allow navigation to private/internal network addresses.
|
|
18
|
+
* Default: `true` (trusted-network mode). Set to `false` for strict public-only enforcement.
|
|
19
|
+
*/
|
|
20
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Allow navigation to private/internal network addresses.
|
|
23
|
+
* @deprecated Use `dangerouslyAllowPrivateNetwork` instead.
|
|
24
|
+
*/
|
|
16
25
|
allowPrivateNetwork?: boolean;
|
|
17
26
|
/** Hostnames explicitly allowed even if they resolve to private addresses */
|
|
18
27
|
allowedHostnames?: string[];
|
|
@@ -48,12 +57,13 @@ interface LaunchOptions {
|
|
|
48
57
|
chromeArgs?: string[];
|
|
49
58
|
/**
|
|
50
59
|
* SSRF policy controlling which URLs navigation is allowed to reach.
|
|
51
|
-
*
|
|
60
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
61
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
52
62
|
*/
|
|
53
63
|
ssrfPolicy?: SsrfPolicy;
|
|
54
64
|
/**
|
|
55
65
|
* Allow navigation to internal/loopback addresses (localhost, 127.x, private IPs).
|
|
56
|
-
* @deprecated Use `ssrfPolicy: {
|
|
66
|
+
* @deprecated Use `ssrfPolicy: { dangerouslyAllowPrivateNetwork: true }` instead.
|
|
57
67
|
*/
|
|
58
68
|
allowInternal?: boolean;
|
|
59
69
|
}
|
|
@@ -61,12 +71,13 @@ interface LaunchOptions {
|
|
|
61
71
|
interface ConnectOptions {
|
|
62
72
|
/**
|
|
63
73
|
* SSRF policy controlling which URLs navigation is allowed to reach.
|
|
64
|
-
*
|
|
74
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
75
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
65
76
|
*/
|
|
66
77
|
ssrfPolicy?: SsrfPolicy;
|
|
67
78
|
/**
|
|
68
79
|
* Allow navigation to internal/loopback addresses (localhost, 127.x, private IPs).
|
|
69
|
-
* @deprecated Use `ssrfPolicy: {
|
|
80
|
+
* @deprecated Use `ssrfPolicy: { dangerouslyAllowPrivateNetwork: true }` instead.
|
|
70
81
|
*/
|
|
71
82
|
allowInternal?: boolean;
|
|
72
83
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -9,10 +9,19 @@ interface FrameEvalResult {
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Policy for controlling which URLs browser navigation is allowed to reach.
|
|
12
|
-
*
|
|
12
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
13
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
13
14
|
*/
|
|
14
15
|
interface SsrfPolicy {
|
|
15
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Allow navigation to private/internal network addresses.
|
|
18
|
+
* Default: `true` (trusted-network mode). Set to `false` for strict public-only enforcement.
|
|
19
|
+
*/
|
|
20
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Allow navigation to private/internal network addresses.
|
|
23
|
+
* @deprecated Use `dangerouslyAllowPrivateNetwork` instead.
|
|
24
|
+
*/
|
|
16
25
|
allowPrivateNetwork?: boolean;
|
|
17
26
|
/** Hostnames explicitly allowed even if they resolve to private addresses */
|
|
18
27
|
allowedHostnames?: string[];
|
|
@@ -48,12 +57,13 @@ interface LaunchOptions {
|
|
|
48
57
|
chromeArgs?: string[];
|
|
49
58
|
/**
|
|
50
59
|
* SSRF policy controlling which URLs navigation is allowed to reach.
|
|
51
|
-
*
|
|
60
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
61
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
52
62
|
*/
|
|
53
63
|
ssrfPolicy?: SsrfPolicy;
|
|
54
64
|
/**
|
|
55
65
|
* Allow navigation to internal/loopback addresses (localhost, 127.x, private IPs).
|
|
56
|
-
* @deprecated Use `ssrfPolicy: {
|
|
66
|
+
* @deprecated Use `ssrfPolicy: { dangerouslyAllowPrivateNetwork: true }` instead.
|
|
57
67
|
*/
|
|
58
68
|
allowInternal?: boolean;
|
|
59
69
|
}
|
|
@@ -61,12 +71,13 @@ interface LaunchOptions {
|
|
|
61
71
|
interface ConnectOptions {
|
|
62
72
|
/**
|
|
63
73
|
* SSRF policy controlling which URLs navigation is allowed to reach.
|
|
64
|
-
*
|
|
74
|
+
* Defaults to trusted-network mode (private/internal addresses allowed).
|
|
75
|
+
* Set `dangerouslyAllowPrivateNetwork: false` to enforce strict public-only checks.
|
|
65
76
|
*/
|
|
66
77
|
ssrfPolicy?: SsrfPolicy;
|
|
67
78
|
/**
|
|
68
79
|
* Allow navigation to internal/loopback addresses (localhost, 127.x, private IPs).
|
|
69
|
-
* @deprecated Use `ssrfPolicy: {
|
|
80
|
+
* @deprecated Use `ssrfPolicy: { dangerouslyAllowPrivateNetwork: true }` instead.
|
|
70
81
|
*/
|
|
71
82
|
allowInternal?: boolean;
|
|
72
83
|
/**
|
package/dist/index.js
CHANGED
|
@@ -346,7 +346,9 @@ async function isChromeReachable(cdpUrl, timeoutMs = 500, authToken) {
|
|
|
346
346
|
const headers = {};
|
|
347
347
|
if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
|
|
348
348
|
const res = await fetch(`${cdpUrl.replace(/\/+$/, "")}/json/version`, { signal: ctrl.signal, headers });
|
|
349
|
-
|
|
349
|
+
if (!res.ok) return false;
|
|
350
|
+
const data = await res.json();
|
|
351
|
+
return data != null && typeof data === "object";
|
|
350
352
|
} catch {
|
|
351
353
|
return false;
|
|
352
354
|
} finally {
|
|
@@ -362,6 +364,7 @@ async function getChromeWebSocketUrl(cdpUrl, timeoutMs = 500, authToken) {
|
|
|
362
364
|
const res = await fetch(`${cdpUrl.replace(/\/+$/, "")}/json/version`, { signal: ctrl.signal, headers });
|
|
363
365
|
if (!res.ok) return null;
|
|
364
366
|
const data = await res.json();
|
|
367
|
+
if (!data || typeof data !== "object") return null;
|
|
365
368
|
return String(data?.webSocketDebuggerUrl ?? "").trim() || null;
|
|
366
369
|
} catch {
|
|
367
370
|
return null;
|
|
@@ -1403,7 +1406,7 @@ async function assertBrowserNavigationAllowed(opts) {
|
|
|
1403
1406
|
throw new InvalidBrowserNavigationUrlError(`Navigation blocked: unsupported protocol "${parsed.protocol}"`);
|
|
1404
1407
|
}
|
|
1405
1408
|
const policy = opts.ssrfPolicy;
|
|
1406
|
-
if (policy?.allowPrivateNetwork) return;
|
|
1409
|
+
if (policy?.dangerouslyAllowPrivateNetwork ?? policy?.allowPrivateNetwork ?? true) return;
|
|
1407
1410
|
const allowedHostnames = [
|
|
1408
1411
|
...policy?.allowedHostnames ?? [],
|
|
1409
1412
|
...policy?.hostnameAllowlist ?? []
|
|
@@ -1414,7 +1417,7 @@ async function assertBrowserNavigationAllowed(opts) {
|
|
|
1414
1417
|
}
|
|
1415
1418
|
if (await isInternalUrlResolved(rawUrl, opts.lookupFn)) {
|
|
1416
1419
|
throw new InvalidBrowserNavigationUrlError(
|
|
1417
|
-
`Navigation to internal/loopback address blocked: "${rawUrl}".
|
|
1420
|
+
`Navigation to internal/loopback address blocked: "${rawUrl}". ssrfPolicy.dangerouslyAllowPrivateNetwork is false (strict mode).`
|
|
1418
1421
|
);
|
|
1419
1422
|
}
|
|
1420
1423
|
}
|
|
@@ -1561,7 +1564,7 @@ async function isInternalUrlResolved(url, lookupFn = lookup) {
|
|
|
1561
1564
|
async function navigateViaPlaywright(opts) {
|
|
1562
1565
|
const url = String(opts.url ?? "").trim();
|
|
1563
1566
|
if (!url) throw new Error("url is required");
|
|
1564
|
-
const policy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
1567
|
+
const policy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
1565
1568
|
await assertBrowserNavigationAllowed({ url, ssrfPolicy: policy });
|
|
1566
1569
|
const page = await getPageForTargetId({ cdpUrl: opts.cdpUrl, targetId: opts.targetId });
|
|
1567
1570
|
ensurePageState(page);
|
|
@@ -1586,7 +1589,7 @@ async function listPagesViaPlaywright(opts) {
|
|
|
1586
1589
|
async function createPageViaPlaywright(opts) {
|
|
1587
1590
|
const targetUrl = (opts.url ?? "").trim() || "about:blank";
|
|
1588
1591
|
if (targetUrl !== "about:blank") {
|
|
1589
|
-
const policy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
1592
|
+
const policy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
1590
1593
|
await assertBrowserNavigationAllowed({ url: targetUrl, ssrfPolicy: policy });
|
|
1591
1594
|
}
|
|
1592
1595
|
const { browser } = await connectBrowser(opts.cdpUrl);
|
|
@@ -3010,7 +3013,7 @@ var BrowserClaw = class _BrowserClaw {
|
|
|
3010
3013
|
static async launch(opts = {}) {
|
|
3011
3014
|
const chrome = await launchChrome(opts);
|
|
3012
3015
|
const cdpUrl = `http://127.0.0.1:${chrome.cdpPort}`;
|
|
3013
|
-
const ssrfPolicy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
3016
|
+
const ssrfPolicy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
3014
3017
|
return new _BrowserClaw(cdpUrl, chrome, ssrfPolicy);
|
|
3015
3018
|
}
|
|
3016
3019
|
/**
|
|
@@ -3032,7 +3035,7 @@ var BrowserClaw = class _BrowserClaw {
|
|
|
3032
3035
|
throw new Error(`Cannot connect to Chrome at ${cdpUrl}. Is Chrome running with --remote-debugging-port?`);
|
|
3033
3036
|
}
|
|
3034
3037
|
await connectBrowser(cdpUrl, opts?.authToken);
|
|
3035
|
-
const ssrfPolicy = opts?.allowInternal ? { ...opts.ssrfPolicy,
|
|
3038
|
+
const ssrfPolicy = opts?.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts?.ssrfPolicy;
|
|
3036
3039
|
return new _BrowserClaw(cdpUrl, null, ssrfPolicy);
|
|
3037
3040
|
}
|
|
3038
3041
|
/**
|