@crewhaus/tool-navigate 0.4.0 → 0.5.0

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.d.ts CHANGED
@@ -23,8 +23,24 @@ export declare function _setDnsLookup(fn: DnsLookupFn | undefined): void;
23
23
  * elsewhere, so for that backend this pre-goto guard is still the only
24
24
  * navigate-side control; pin egress at the remote browser's host.
25
25
  */
26
- export declare function assertSafeNavigationTarget(rawUrl: string): Promise<void>;
26
+ export declare function assertSafeNavigationTarget(rawUrl: string, opts?: {
27
+ readonly allowPrivateTargets?: boolean;
28
+ }): Promise<void>;
27
29
  export type CreateNavigateToolOptions = {
28
30
  readonly driver: Driver;
31
+ /**
32
+ * SECURITY — spec `driver.allowPrivateTargets: true`. Waives ONLY the
33
+ * private/loopback/mDNS host checks, for a harness whose whole job is a
34
+ * private target the operator controls: an intranet app under test, or a
35
+ * locally-served fixture page. The scheme allowlist is never waived, so an
36
+ * opted-in spec still cannot reach `file:`/`data:`/`chrome:`.
37
+ *
38
+ * Default false, and a per-spec compile-time decision — there is
39
+ * deliberately no env var or global switch, so it cannot be turned on by an
40
+ * ambient misconfiguration, and a reviewer sees it in the spec diff. The
41
+ * chromium backend drops its DNS-pinning proxy under the same flag, so the
42
+ * two layers agree instead of one silently 403ing what the other allowed.
43
+ */
44
+ readonly allowPrivateTargets?: boolean;
29
45
  };
30
46
  export declare function createNavigateTool(opts: CreateNavigateToolOptions): RegisteredTool;
package/dist/index.js CHANGED
@@ -174,7 +174,7 @@ function isPrivateIp(addr) {
174
174
  * elsewhere, so for that backend this pre-goto guard is still the only
175
175
  * navigate-side control; pin egress at the remote browser's host.
176
176
  */
177
- export async function assertSafeNavigationTarget(rawUrl) {
177
+ export async function assertSafeNavigationTarget(rawUrl, opts = {}) {
178
178
  let url;
179
179
  try {
180
180
  url = new URL(rawUrl);
@@ -185,6 +185,8 @@ export async function assertSafeNavigationTarget(rawUrl) {
185
185
  if (!ALLOWED_SCHEMES.has(url.protocol)) {
186
186
  throw new NavigateError(`navigation to ${rawUrl} blocked: only http/https is allowed (got "${url.protocol}")`);
187
187
  }
188
+ if (opts.allowPrivateTargets === true)
189
+ return;
188
190
  const hostname = url.hostname.toLowerCase();
189
191
  if (hostname === "localhost" || hostname.endsWith(".localhost")) {
190
192
  throw new NavigateError(`navigation to ${rawUrl} blocked: loopback host`);
@@ -224,7 +226,9 @@ export function createNavigateTool(opts) {
224
226
  execute: async (input) => {
225
227
  // SSRF guard runs BEFORE the browser touches the URL. Throws
226
228
  // NavigateError directly so the block reason surfaces unwrapped.
227
- await assertSafeNavigationTarget(input.url);
229
+ await assertSafeNavigationTarget(input.url, {
230
+ allowPrivateTargets: opts.allowPrivateTargets === true,
231
+ });
228
232
  try {
229
233
  await opts.driver.goto(input.url);
230
234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewhaus/tool-navigate",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "Navigate tool — drives driver.goto(url) for the BROW agent (Section 25 BROW)",
6
6
  "main": "dist/index.js",
@@ -15,10 +15,10 @@
15
15
  "test": "bun test src"
16
16
  },
17
17
  "dependencies": {
18
- "@crewhaus/computer-use-driver": "0.4.0",
19
- "@crewhaus/errors": "0.4.0",
20
- "@crewhaus/tool-builder": "0.4.0",
21
- "@crewhaus/tool-catalog": "0.4.0",
18
+ "@crewhaus/computer-use-driver": "0.5.0",
19
+ "@crewhaus/errors": "0.5.0",
20
+ "@crewhaus/tool-builder": "0.5.0",
21
+ "@crewhaus/tool-catalog": "0.5.0",
22
22
  "zod": "^3.23.8"
23
23
  },
24
24
  "license": "Apache-2.0",