@agenttool/browser 0.1.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/CLAUDE.md +66 -0
- package/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +295 -0
- package/dist/bin/agenttool-browser.d.ts +3 -0
- package/dist/bin/agenttool-browser.d.ts.map +1 -0
- package/dist/bin/agenttool-browser.js +11 -0
- package/dist/bin/agenttool-browser.js.map +1 -0
- package/dist/src/browser.d.ts +56 -0
- package/dist/src/browser.d.ts.map +1 -0
- package/dist/src/browser.js +1354 -0
- package/dist/src/browser.js.map +1 -0
- package/dist/src/cli.d.ts +33 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +447 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +40 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +219 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/errors.d.ts +11 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +20 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp.d.ts +76 -0
- package/dist/src/mcp.d.ts.map +1 -0
- package/dist/src/mcp.js +408 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/policy.d.ts +49 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/policy.js +315 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/snapshot.d.ts +45 -0
- package/dist/src/snapshot.d.ts.map +1 -0
- package/dist/src/snapshot.js +184 -0
- package/dist/src/snapshot.js.map +1 -0
- package/dist/src/types.d.ts +352 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { lookup } from "node:dns/promises";
|
|
2
|
+
import { isIP } from "node:net";
|
|
3
|
+
import { BrowserError } from "./errors.js";
|
|
4
|
+
export async function defaultResolveHostname(hostname) {
|
|
5
|
+
return lookup(hostname, { all: true, verbatim: true });
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Construction-fixed navigation policy.
|
|
9
|
+
*
|
|
10
|
+
* DNS checks are a useful local safety boundary, not an SSRF sandbox. Chromium
|
|
11
|
+
* performs its own DNS resolution after this check, so DNS rebinding creates a
|
|
12
|
+
* time-of-check/time-of-use gap and the connected address is not pinned.
|
|
13
|
+
*/
|
|
14
|
+
export class BrowserNetworkPolicy {
|
|
15
|
+
boundary;
|
|
16
|
+
allowPublicWeb;
|
|
17
|
+
allowLocalNetwork;
|
|
18
|
+
resolveHostname;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.allowPublicWeb = options.allowPublicWeb ?? true;
|
|
21
|
+
this.allowLocalNetwork = options.allowLocalNetwork ?? false;
|
|
22
|
+
this.resolveHostname = options.resolveHostname ?? defaultResolveHostname;
|
|
23
|
+
this.boundary = Object.freeze({
|
|
24
|
+
mode: "local_browser_public_web",
|
|
25
|
+
publicWeb: this.allowPublicWeb,
|
|
26
|
+
localNetwork: this.allowLocalNetwork,
|
|
27
|
+
schemes: Object.freeze(["http", "https"]),
|
|
28
|
+
urlCredentials: "blocked",
|
|
29
|
+
dnsPreflight: true,
|
|
30
|
+
connectionAddressPinning: false,
|
|
31
|
+
webSockets: "blocked",
|
|
32
|
+
statement: "HTTP(S) destinations are checked before browser requests; DNS preflight does not pin Chromium's connected address.",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async assertAllowed(input) {
|
|
36
|
+
const url = parseBrowserUrl(input);
|
|
37
|
+
const hostname = normalizeHostname(url.hostname);
|
|
38
|
+
const namedClass = classifySpecialHostname(hostname);
|
|
39
|
+
if (namedClass) {
|
|
40
|
+
this.assertClassAllowed(namedClass);
|
|
41
|
+
return url;
|
|
42
|
+
}
|
|
43
|
+
if (isIP(hostname) !== 0) {
|
|
44
|
+
this.assertClassAllowed(classifyIpAddress(hostname));
|
|
45
|
+
return url;
|
|
46
|
+
}
|
|
47
|
+
let addresses;
|
|
48
|
+
try {
|
|
49
|
+
addresses = await this.resolveHostname(hostname);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new BrowserError("dns_failed", "Browser policy could not resolve the destination.", { cause: error });
|
|
53
|
+
}
|
|
54
|
+
if (addresses.length === 0) {
|
|
55
|
+
throw new BrowserError("dns_failed", "Browser policy could not resolve the destination.");
|
|
56
|
+
}
|
|
57
|
+
for (const address of addresses) {
|
|
58
|
+
this.assertClassAllowed(classifyIpAddress(address.address));
|
|
59
|
+
}
|
|
60
|
+
return url;
|
|
61
|
+
}
|
|
62
|
+
assertClassAllowed(destination) {
|
|
63
|
+
if (destination === "reserved") {
|
|
64
|
+
throw new BrowserError("network_blocked", "Browser policy blocks reserved network destinations.");
|
|
65
|
+
}
|
|
66
|
+
if (destination === "local" && !this.allowLocalNetwork) {
|
|
67
|
+
throw new BrowserError("network_blocked", "Browser policy blocks localhost and private network destinations by default.");
|
|
68
|
+
}
|
|
69
|
+
if (destination === "public" && !this.allowPublicWeb) {
|
|
70
|
+
throw new BrowserError("network_blocked", "Browser policy does not permit public web destinations.");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function parseBrowserUrl(input) {
|
|
75
|
+
let url;
|
|
76
|
+
try {
|
|
77
|
+
url = input instanceof URL ? new URL(input.href) : new URL(input);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
throw new BrowserError("invalid_url", "URL must be absolute.", { cause: error });
|
|
81
|
+
}
|
|
82
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
83
|
+
throw new BrowserError("url_scheme_blocked", "Browser navigation only permits http: and https: URLs.");
|
|
84
|
+
}
|
|
85
|
+
if (url.username || url.password) {
|
|
86
|
+
throw new BrowserError("url_credentials_blocked", "Credentials are not permitted in browser URLs.");
|
|
87
|
+
}
|
|
88
|
+
return url;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Redact query values at every structured URL boundary. Paths, fragments, and
|
|
92
|
+
* screenshot pixels are outside this filter; free-form text has a separate
|
|
93
|
+
* URL sanitizer.
|
|
94
|
+
*/
|
|
95
|
+
export function redactUrlForOutput(input) {
|
|
96
|
+
let url;
|
|
97
|
+
try {
|
|
98
|
+
url = new URL(input);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return input;
|
|
102
|
+
}
|
|
103
|
+
url.username = "";
|
|
104
|
+
url.password = "";
|
|
105
|
+
if (url.search) {
|
|
106
|
+
const redacted = new URLSearchParams();
|
|
107
|
+
for (const [name] of url.searchParams)
|
|
108
|
+
redacted.append(name, "[redacted]");
|
|
109
|
+
url.search = redacted.toString();
|
|
110
|
+
}
|
|
111
|
+
return url.href;
|
|
112
|
+
}
|
|
113
|
+
export function redactUrlsInText(input) {
|
|
114
|
+
return input.replace(/https?:\/\/[^\s<>"'`]+/gi, (candidate) => {
|
|
115
|
+
const trailing = candidate.match(/[),.;!?]+$/)?.[0] ?? "";
|
|
116
|
+
const url = trailing ? candidate.slice(0, -trailing.length) : candidate;
|
|
117
|
+
return `${redactUrlForOutput(url)}${trailing}`;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
export function redactHtmlUrlAttributes(input) {
|
|
121
|
+
return input.replace(/(\s+(?:href|src|action|formaction|poster)\s*=\s*)("[^"]*"|'[^']*'|[^\s>]+)/gi, (_match, prefix, encodedValue) => {
|
|
122
|
+
const quote = encodedValue.startsWith('"') || encodedValue.startsWith("'")
|
|
123
|
+
? encodedValue[0]
|
|
124
|
+
: "";
|
|
125
|
+
const value = quote ? encodedValue.slice(1, -1) : encodedValue;
|
|
126
|
+
return `${prefix}${quote}${redactUrlReferenceForOutput(value)}${quote}`;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/** Redact query values while preserving an absolute, protocol-relative, or relative reference. */
|
|
130
|
+
export function redactUrlReferenceForOutput(input) {
|
|
131
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(input))
|
|
132
|
+
return redactUrlForOutput(input);
|
|
133
|
+
if (input.startsWith("//")) {
|
|
134
|
+
try {
|
|
135
|
+
const redacted = new URL(redactUrlForOutput(`https:${input}`));
|
|
136
|
+
return `//${redacted.host}${redacted.pathname}${redacted.search}${redacted.hash}`;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Fall through to the query-only redactor.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const queryStart = input.indexOf("?");
|
|
143
|
+
if (queryStart < 0)
|
|
144
|
+
return input;
|
|
145
|
+
const fragmentStart = input.indexOf("#", queryStart);
|
|
146
|
+
const queryEnd = fragmentStart < 0 ? input.length : fragmentStart;
|
|
147
|
+
const query = input.slice(queryStart + 1, queryEnd);
|
|
148
|
+
const redacted = new URLSearchParams();
|
|
149
|
+
for (const [name] of new URLSearchParams(query)) {
|
|
150
|
+
redacted.append(name, "[redacted]");
|
|
151
|
+
}
|
|
152
|
+
return (`${input.slice(0, queryStart)}?${redacted.toString()}`
|
|
153
|
+
+ (fragmentStart < 0 ? "" : input.slice(fragmentStart)));
|
|
154
|
+
}
|
|
155
|
+
export function classifyIpAddress(address) {
|
|
156
|
+
const normalized = address.toLowerCase().split("%", 1)[0];
|
|
157
|
+
if (isIP(normalized) === 4)
|
|
158
|
+
return classifyIpv4(normalized);
|
|
159
|
+
if (isIP(normalized) === 6)
|
|
160
|
+
return classifyIpv6(normalized);
|
|
161
|
+
return "reserved";
|
|
162
|
+
}
|
|
163
|
+
export function isPrivateOrReservedAddress(address) {
|
|
164
|
+
return classifyIpAddress(address) !== "public";
|
|
165
|
+
}
|
|
166
|
+
function normalizeHostname(hostname) {
|
|
167
|
+
return hostname
|
|
168
|
+
.replace(/^\[|\]$/g, "")
|
|
169
|
+
.replace(/\.$/, "")
|
|
170
|
+
.toLowerCase();
|
|
171
|
+
}
|
|
172
|
+
function classifySpecialHostname(hostname) {
|
|
173
|
+
if (hostname === "localhost"
|
|
174
|
+
|| hostname.endsWith(".localhost")
|
|
175
|
+
|| hostname === "local"
|
|
176
|
+
|| hostname.endsWith(".local")
|
|
177
|
+
|| hostname === "home.arpa"
|
|
178
|
+
|| hostname.endsWith(".home.arpa")
|
|
179
|
+
|| hostname === "internal"
|
|
180
|
+
|| hostname.endsWith(".internal")) {
|
|
181
|
+
return "local";
|
|
182
|
+
}
|
|
183
|
+
if (hostname === "test"
|
|
184
|
+
|| hostname.endsWith(".test")
|
|
185
|
+
|| hostname === "invalid"
|
|
186
|
+
|| hostname.endsWith(".invalid")
|
|
187
|
+
|| hostname === "example"
|
|
188
|
+
|| hostname.endsWith(".example")
|
|
189
|
+
|| hostname === "onion"
|
|
190
|
+
|| hostname.endsWith(".onion")) {
|
|
191
|
+
return "reserved";
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
function classifyIpv4(address) {
|
|
196
|
+
const parts = address.split(".").map(Number);
|
|
197
|
+
const [a, b, c] = parts;
|
|
198
|
+
if (a === undefined || b === undefined || c === undefined)
|
|
199
|
+
return "reserved";
|
|
200
|
+
if (a === 10
|
|
201
|
+
|| a === 127
|
|
202
|
+
|| (a === 100 && b >= 64 && b <= 127)
|
|
203
|
+
|| (a === 169 && b === 254)
|
|
204
|
+
|| (a === 172 && b >= 16 && b <= 31)
|
|
205
|
+
|| (a === 192 && b === 168)) {
|
|
206
|
+
return "local";
|
|
207
|
+
}
|
|
208
|
+
if (a === 0
|
|
209
|
+
|| (a === 192 && b === 0)
|
|
210
|
+
|| (a === 192 && b === 88 && c === 99)
|
|
211
|
+
|| (a === 198 && (b === 18 || b === 19))
|
|
212
|
+
|| (a === 198 && b === 51 && c === 100)
|
|
213
|
+
|| (a === 203 && b === 0 && c === 113)
|
|
214
|
+
|| a >= 224) {
|
|
215
|
+
return "reserved";
|
|
216
|
+
}
|
|
217
|
+
return "public";
|
|
218
|
+
}
|
|
219
|
+
function classifyIpv6(address) {
|
|
220
|
+
const bytes = parseIpv6(address);
|
|
221
|
+
if (!bytes)
|
|
222
|
+
return "reserved";
|
|
223
|
+
if (bytes.every((byte) => byte === 0))
|
|
224
|
+
return "local";
|
|
225
|
+
if (bytes.slice(0, 15).every((byte) => byte === 0) && bytes[15] === 1) {
|
|
226
|
+
return "local";
|
|
227
|
+
}
|
|
228
|
+
if ((bytes[0] & 0xfe) === 0xfc)
|
|
229
|
+
return "local";
|
|
230
|
+
if (bytes[0] === 0xfe && (bytes[1] & 0xc0) === 0x80)
|
|
231
|
+
return "local";
|
|
232
|
+
if (bytes[0] === 0xfe && (bytes[1] & 0xc0) === 0xc0)
|
|
233
|
+
return "local";
|
|
234
|
+
if (bytes[0] === 0xff)
|
|
235
|
+
return "reserved";
|
|
236
|
+
if (bytes[0] === 0x20
|
|
237
|
+
&& bytes[1] === 0x01
|
|
238
|
+
&& bytes[2] === 0x0d
|
|
239
|
+
&& bytes[3] === 0xb8) {
|
|
240
|
+
return "reserved";
|
|
241
|
+
}
|
|
242
|
+
const firstTenZero = bytes.slice(0, 10).every((byte) => byte === 0);
|
|
243
|
+
if (firstTenZero && bytes[10] === 0xff && bytes[11] === 0xff) {
|
|
244
|
+
return classifyEmbeddedIpv4(bytes, 12);
|
|
245
|
+
}
|
|
246
|
+
const firstTwelveZero = bytes.slice(0, 12).every((byte) => byte === 0);
|
|
247
|
+
if (firstTwelveZero)
|
|
248
|
+
return classifyEmbeddedIpv4(bytes, 12);
|
|
249
|
+
const nat64 = bytes[0] === 0x00
|
|
250
|
+
&& bytes[1] === 0x64
|
|
251
|
+
&& bytes[2] === 0xff
|
|
252
|
+
&& bytes[3] === 0x9b
|
|
253
|
+
&& bytes.slice(4, 12).every((byte) => byte === 0);
|
|
254
|
+
if (nat64)
|
|
255
|
+
return classifyEmbeddedIpv4(bytes, 12);
|
|
256
|
+
const sixToFour = bytes[0] === 0x20 && bytes[1] === 0x02;
|
|
257
|
+
if (sixToFour)
|
|
258
|
+
return classifyEmbeddedIpv4(bytes, 2);
|
|
259
|
+
// IANA protocol assignments, benchmarking/ORCHID ranges and documentation
|
|
260
|
+
// prefixes are not ordinary global-unicast destinations.
|
|
261
|
+
const protocolAssignments = bytes[0] === 0x20
|
|
262
|
+
&& bytes[1] === 0x01
|
|
263
|
+
&& bytes[2] <= 0x01;
|
|
264
|
+
const documentation3fff = bytes[0] === 0x3f
|
|
265
|
+
&& bytes[1] === 0xff
|
|
266
|
+
&& (bytes[2] & 0xf0) === 0;
|
|
267
|
+
if (protocolAssignments || documentation3fff)
|
|
268
|
+
return "reserved";
|
|
269
|
+
// Only 2000::/3 can be globally routed. All other special-purpose IPv6
|
|
270
|
+
// space remains denied even when local-network access is opted in.
|
|
271
|
+
return (bytes[0] & 0xe0) === 0x20 ? "public" : "reserved";
|
|
272
|
+
}
|
|
273
|
+
function classifyEmbeddedIpv4(bytes, offset) {
|
|
274
|
+
return classifyIpv4(`${bytes[offset]}.${bytes[offset + 1]}.${bytes[offset + 2]}.${bytes[offset + 3]}`);
|
|
275
|
+
}
|
|
276
|
+
function parseIpv6(address) {
|
|
277
|
+
let input = address;
|
|
278
|
+
if (input.includes(".")) {
|
|
279
|
+
const separator = input.lastIndexOf(":");
|
|
280
|
+
const ipv4 = input.slice(separator + 1).split(".").map(Number);
|
|
281
|
+
if (separator < 0
|
|
282
|
+
|| ipv4.length !== 4
|
|
283
|
+
|| ipv4.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
input =
|
|
287
|
+
`${input.slice(0, separator)}`
|
|
288
|
+
+ `:${((ipv4[0] << 8) | ipv4[1]).toString(16)}`
|
|
289
|
+
+ `:${((ipv4[2] << 8) | ipv4[3]).toString(16)}`;
|
|
290
|
+
}
|
|
291
|
+
const halves = input.split("::");
|
|
292
|
+
if (halves.length > 2)
|
|
293
|
+
return null;
|
|
294
|
+
const left = halves[0] ? halves[0].split(":") : [];
|
|
295
|
+
const right = halves.length === 2 && halves[1] ? halves[1].split(":") : [];
|
|
296
|
+
const missing = 8 - left.length - right.length;
|
|
297
|
+
if ((halves.length === 1 && missing !== 0)
|
|
298
|
+
|| (halves.length === 2 && missing < 1)) {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const groups = [...left, ...Array.from({ length: missing }, () => "0"), ...right];
|
|
302
|
+
if (groups.length !== 8)
|
|
303
|
+
return null;
|
|
304
|
+
const bytes = new Uint8Array(16);
|
|
305
|
+
for (let index = 0; index < groups.length; index += 1) {
|
|
306
|
+
const group = groups[index];
|
|
307
|
+
if (!/^[a-f0-9]{1,4}$/.test(group))
|
|
308
|
+
return null;
|
|
309
|
+
const value = Number.parseInt(group, 16);
|
|
310
|
+
bytes[index * 2] = value >> 8;
|
|
311
|
+
bytes[index * 2 + 1] = value & 0xff;
|
|
312
|
+
}
|
|
313
|
+
return bytes;
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BoundingBox, BrowserViewport, SnapshotRef } from "./types.js";
|
|
2
|
+
export interface AriaCandidate {
|
|
3
|
+
nativeRef: string;
|
|
4
|
+
role: string;
|
|
5
|
+
name: string | null;
|
|
6
|
+
line: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CompactAriaSnapshotOptions {
|
|
9
|
+
publicRefs: ReadonlyMap<string, string>;
|
|
10
|
+
visibleRefs: ReadonlySet<string>;
|
|
11
|
+
secretRefs?: ReadonlySet<string>;
|
|
12
|
+
maxChars: number;
|
|
13
|
+
maxElements: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CompactAriaSnapshotResult {
|
|
16
|
+
snapshot: string;
|
|
17
|
+
refs: SnapshotRef[];
|
|
18
|
+
truncated: {
|
|
19
|
+
snapshot: boolean;
|
|
20
|
+
elements: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function parseAriaCandidates(snapshot: string): AriaCandidate[];
|
|
24
|
+
export declare function compactAriaSnapshot(rawSnapshot: string, options: CompactAriaSnapshotOptions): CompactAriaSnapshotResult;
|
|
25
|
+
/**
|
|
26
|
+
* Defense-in-depth sanitizer for raw AI-mode snapshots. The compact snapshot
|
|
27
|
+
* path also redacts while rewriting refs, so callers never receive a password
|
|
28
|
+
* value even if Playwright includes it after the textbox node.
|
|
29
|
+
*/
|
|
30
|
+
export declare function redactAriaSecrets(snapshot: string, secretRefs: ReadonlySet<string>): string;
|
|
31
|
+
export declare function looksLikeSensitiveControl(attributes: Readonly<Record<string, string | null>>, accessibleName: string | null): boolean;
|
|
32
|
+
export declare function intersectsViewport(box: BoundingBox | null, viewport: BrowserViewport): boolean;
|
|
33
|
+
export declare function boundText(value: string, maxChars: number): {
|
|
34
|
+
value: string;
|
|
35
|
+
truncated: boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* HTML extraction cannot be a general secret detector, but values on inputs
|
|
39
|
+
* carrying the same recognized password/secret hints as observations are
|
|
40
|
+
* removed before returning markup.
|
|
41
|
+
*/
|
|
42
|
+
export declare function redactSensitiveInputValues(html: string): string;
|
|
43
|
+
/** Backwards-compatible narrow name; now covers every recognized secret hint. */
|
|
44
|
+
export declare function redactPasswordValues(html: string): string;
|
|
45
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA0B5E,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,SAAS,EAAE;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAwBrE;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,0BAA0B,GAClC,yBAAyB,CAgD3B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC9B,MAAM,CAUR;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,EACnD,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,OAAO,CAiBT;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAQT;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAGvC;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB/D;AAED,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const INTERACTIVE_ROLES = new Set([
|
|
2
|
+
"button",
|
|
3
|
+
"checkbox",
|
|
4
|
+
"combobox",
|
|
5
|
+
"gridcell",
|
|
6
|
+
"link",
|
|
7
|
+
"listbox",
|
|
8
|
+
"menuitem",
|
|
9
|
+
"menuitemcheckbox",
|
|
10
|
+
"menuitemradio",
|
|
11
|
+
"option",
|
|
12
|
+
"radio",
|
|
13
|
+
"searchbox",
|
|
14
|
+
"slider",
|
|
15
|
+
"spinbutton",
|
|
16
|
+
"switch",
|
|
17
|
+
"tab",
|
|
18
|
+
"textbox",
|
|
19
|
+
"treeitem",
|
|
20
|
+
]);
|
|
21
|
+
const SENSITIVE_HINT = /\b(?:password|passwd|passcode|pin|secret|token|api[\s_-]*key|private[\s_-]*key|cvv|cvc)\b/i;
|
|
22
|
+
export function parseAriaCandidates(snapshot) {
|
|
23
|
+
const candidates = [];
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
for (const rawLine of snapshot.split(/\r?\n/)) {
|
|
26
|
+
const refMatch = rawLine.match(/\[ref=([A-Za-z0-9_-]+)\]/);
|
|
27
|
+
const roleMatch = rawLine.match(/^\s*-\s+([a-z][a-z0-9_-]*)\b/i);
|
|
28
|
+
if (!refMatch?.[1] || !roleMatch?.[1])
|
|
29
|
+
continue;
|
|
30
|
+
const nativeRef = refMatch[1];
|
|
31
|
+
const role = roleMatch[1].toLowerCase();
|
|
32
|
+
if (seen.has(nativeRef)
|
|
33
|
+
|| (!INTERACTIVE_ROLES.has(role) && !rawLine.includes("[cursor=pointer]"))) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
seen.add(nativeRef);
|
|
37
|
+
candidates.push({
|
|
38
|
+
nativeRef,
|
|
39
|
+
role,
|
|
40
|
+
name: parseAccessibleName(rawLine),
|
|
41
|
+
line: rawLine.trim().replace(/^-\s*/, "- "),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return candidates;
|
|
45
|
+
}
|
|
46
|
+
export function compactAriaSnapshot(rawSnapshot, options) {
|
|
47
|
+
const secretRefs = options.secretRefs ?? new Set();
|
|
48
|
+
const eligible = parseAriaCandidates(rawSnapshot).filter((candidate) => options.visibleRefs.has(candidate.nativeRef)
|
|
49
|
+
&& options.publicRefs.has(candidate.nativeRef));
|
|
50
|
+
const refs = [];
|
|
51
|
+
const lines = [];
|
|
52
|
+
let usedChars = 0;
|
|
53
|
+
let snapshotTruncated = false;
|
|
54
|
+
for (const candidate of eligible) {
|
|
55
|
+
if (refs.length >= options.maxElements)
|
|
56
|
+
break;
|
|
57
|
+
const publicRef = options.publicRefs.get(candidate.nativeRef);
|
|
58
|
+
const secret = secretRefs.has(candidate.nativeRef);
|
|
59
|
+
let line = candidate.line.replace(`[ref=${candidate.nativeRef}]`, `[ref=${publicRef}]`);
|
|
60
|
+
if (secret)
|
|
61
|
+
line = redactLineValue(line, publicRef);
|
|
62
|
+
const addition = (lines.length === 0 ? 0 : 1) + line.length;
|
|
63
|
+
if (usedChars + addition > options.maxChars) {
|
|
64
|
+
snapshotTruncated = true;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
lines.push(line);
|
|
68
|
+
usedChars += addition;
|
|
69
|
+
refs.push({
|
|
70
|
+
ref: publicRef,
|
|
71
|
+
role: candidate.role,
|
|
72
|
+
name: candidate.name,
|
|
73
|
+
secret,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const elementsTruncated = eligible.length > refs.length;
|
|
77
|
+
if (elementsTruncated && refs.length >= options.maxElements) {
|
|
78
|
+
snapshotTruncated = true;
|
|
79
|
+
}
|
|
80
|
+
const empty = "(no viewport-visible interactive elements)";
|
|
81
|
+
return {
|
|
82
|
+
snapshot: lines.join("\n") || empty.slice(0, options.maxChars),
|
|
83
|
+
refs,
|
|
84
|
+
truncated: {
|
|
85
|
+
snapshot: snapshotTruncated,
|
|
86
|
+
elements: elementsTruncated,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Defense-in-depth sanitizer for raw AI-mode snapshots. The compact snapshot
|
|
92
|
+
* path also redacts while rewriting refs, so callers never receive a password
|
|
93
|
+
* value even if Playwright includes it after the textbox node.
|
|
94
|
+
*/
|
|
95
|
+
export function redactAriaSecrets(snapshot, secretRefs) {
|
|
96
|
+
return snapshot
|
|
97
|
+
.split(/\r?\n/)
|
|
98
|
+
.map((line) => {
|
|
99
|
+
for (const ref of secretRefs) {
|
|
100
|
+
if (line.includes(`[ref=${ref}]`))
|
|
101
|
+
return redactLineValue(line, ref);
|
|
102
|
+
}
|
|
103
|
+
return line;
|
|
104
|
+
})
|
|
105
|
+
.join("\n");
|
|
106
|
+
}
|
|
107
|
+
export function looksLikeSensitiveControl(attributes, accessibleName) {
|
|
108
|
+
if ((attributes.type ?? "").toLowerCase() === "password")
|
|
109
|
+
return true;
|
|
110
|
+
const autocomplete = (attributes.autocomplete ?? "").toLowerCase();
|
|
111
|
+
if (autocomplete.includes("current-password")
|
|
112
|
+
|| autocomplete.includes("new-password")
|
|
113
|
+
|| autocomplete.includes("one-time-code")) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return [
|
|
117
|
+
accessibleName,
|
|
118
|
+
attributes.name,
|
|
119
|
+
attributes.id,
|
|
120
|
+
attributes.placeholder,
|
|
121
|
+
attributes["aria-label"],
|
|
122
|
+
].some((value) => value !== null && value !== undefined && SENSITIVE_HINT.test(value));
|
|
123
|
+
}
|
|
124
|
+
export function intersectsViewport(box, viewport) {
|
|
125
|
+
if (!box || box.width <= 0 || box.height <= 0)
|
|
126
|
+
return false;
|
|
127
|
+
return (box.x < viewport.width
|
|
128
|
+
&& box.y < viewport.height
|
|
129
|
+
&& box.x + box.width > 0
|
|
130
|
+
&& box.y + box.height > 0);
|
|
131
|
+
}
|
|
132
|
+
export function boundText(value, maxChars) {
|
|
133
|
+
if (value.length <= maxChars)
|
|
134
|
+
return { value, truncated: false };
|
|
135
|
+
return { value: value.slice(0, maxChars), truncated: true };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* HTML extraction cannot be a general secret detector, but values on inputs
|
|
139
|
+
* carrying the same recognized password/secret hints as observations are
|
|
140
|
+
* removed before returning markup.
|
|
141
|
+
*/
|
|
142
|
+
export function redactSensitiveInputValues(html) {
|
|
143
|
+
return html.replace(/<input\b[^>]*>/gi, (tag) => {
|
|
144
|
+
const attributes = {
|
|
145
|
+
type: inputAttribute(tag, "type"),
|
|
146
|
+
autocomplete: inputAttribute(tag, "autocomplete"),
|
|
147
|
+
name: inputAttribute(tag, "name"),
|
|
148
|
+
id: inputAttribute(tag, "id"),
|
|
149
|
+
placeholder: inputAttribute(tag, "placeholder"),
|
|
150
|
+
"aria-label": inputAttribute(tag, "aria-label"),
|
|
151
|
+
};
|
|
152
|
+
if (!looksLikeSensitiveControl(attributes, null))
|
|
153
|
+
return tag;
|
|
154
|
+
return tag.replace(/(\s+value\s*=\s*)(?:"[^"]*"|'[^']*'|[^\s>]+)/i, '$1"[redacted]"');
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/** Backwards-compatible narrow name; now covers every recognized secret hint. */
|
|
158
|
+
export function redactPasswordValues(html) {
|
|
159
|
+
return redactSensitiveInputValues(html);
|
|
160
|
+
}
|
|
161
|
+
function parseAccessibleName(line) {
|
|
162
|
+
const match = line.match(/^\s*-\s+[a-z][a-z0-9_-]*\s+"((?:[^"\\]|\\.)*)"/i);
|
|
163
|
+
if (!match?.[1])
|
|
164
|
+
return null;
|
|
165
|
+
try {
|
|
166
|
+
return JSON.parse(`"${match[1]}"`);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return match[1];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function redactLineValue(line, ref) {
|
|
173
|
+
const refEnd = line.indexOf(`[ref=${ref}]`) + `[ref=${ref}]`.length;
|
|
174
|
+
const valueSeparator = line.indexOf(":", refEnd);
|
|
175
|
+
if (valueSeparator < 0)
|
|
176
|
+
return line;
|
|
177
|
+
return `${line.slice(0, valueSeparator)}: [redacted]`;
|
|
178
|
+
}
|
|
179
|
+
function inputAttribute(tag, name) {
|
|
180
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
181
|
+
const match = tag.match(new RegExp(`\\s+${escapedName}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i"));
|
|
182
|
+
return match?.[1] ?? match?.[2] ?? match?.[3] ?? null;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/snapshot.ts"],"names":[],"mappings":"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"}
|