agent-sanitizer 2.63.0 → 2.64.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/README.md +1 -0
- package/THREAT-MODEL.md +41 -17
- package/claude-hooks/lib/redactor-client.mjs +60 -5
- package/claude-hooks/sanitize-output.mjs +41 -269
- package/package.json +1 -1
- package/src/cf-charset.mjs +5 -4
- package/src/confusable-host.mjs +18 -14
- package/src/confusables.mjs +43 -5
- package/src/gates.mjs +53 -21
- package/src/html.mjs +72 -59
- package/src/index.mjs +1 -0
- package/src/invisible.mjs +2 -0
- package/src/joining-type.mjs +4 -3
- package/src/output.mjs +421 -297
- package/src/severity.mjs +14 -2
- package/src/standardized-variants.mjs +4 -4
- package/src/unicode-properties.mjs +335 -3
- package/src/view-map.mjs +6 -4
- package/src/warnings.mjs +7 -0
- package/types/cf-charset.d.mts +5 -4
- package/types/claude-hooks/lib/redactor-client.d.mts +18 -0
- package/types/claude-hooks/sanitize-output.d.mts +14 -30
- package/types/confusable-host.d.mts +7 -6
- package/types/confusables.d.mts +12 -0
- package/types/gates.d.mts +30 -17
- package/types/html.d.mts +4 -2
- package/types/index.d.mts +1 -1
- package/types/invisible.d.mts +1 -0
- package/types/joining-type.d.mts +4 -3
- package/types/output.d.mts +131 -39
- package/types/severity.d.mts +0 -4
- package/types/src/cf-charset.d.mts +5 -4
- package/types/src/invisible.d.mts +1 -0
- package/types/src/joining-type.d.mts +4 -3
- package/types/src/standardized-variants.d.mts +3 -3
- package/types/src/unicode-properties.d.mts +6 -3
- package/types/standardized-variants.d.mts +3 -3
- package/types/unicode-properties.d.mts +6 -3
- package/types/view-map.d.mts +2 -0
- package/types/warnings.d.mts +5 -0
package/src/severity.mjs
CHANGED
|
@@ -45,13 +45,25 @@ export const SEVERITY = Object.freeze({
|
|
|
45
45
|
* A single reportable outcome and how loudly to report it.
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* The message, refused when empty: an unreported change fails at construction
|
|
50
|
+
* instead of rendering as a blank banner line.
|
|
51
|
+
* @param {string} message
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
54
|
+
function reportable(message) {
|
|
55
|
+
if (typeof message !== "string" || message === "")
|
|
56
|
+
throw new TypeError("agent-sanitizer: a finding needs a non-empty message");
|
|
57
|
+
return message;
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
/**
|
|
49
61
|
* A WARNING-severity finding: injection-shaped, worth the banner.
|
|
50
62
|
* @param {string} message
|
|
51
63
|
* @returns {Finding}
|
|
52
64
|
*/
|
|
53
65
|
export function warning(message) {
|
|
54
|
-
return { severity: SEVERITY.WARNING, message };
|
|
66
|
+
return { severity: SEVERITY.WARNING, message: reportable(message) };
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
/**
|
|
@@ -60,7 +72,7 @@ export function warning(message) {
|
|
|
60
72
|
* @returns {Finding}
|
|
61
73
|
*/
|
|
62
74
|
export function note(message) {
|
|
63
|
-
return { severity: SEVERITY.NOTE, message };
|
|
75
|
+
return { severity: SEVERITY.NOTE, message: reportable(message) };
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
/**
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED by scripts/gen-standardized-variants.mjs from UCD
|
|
3
|
-
* StandardizedVariants.txt (Unicode 17.0.0)
|
|
3
|
+
* StandardizedVariants.txt (Unicode 17.0.0) at install time; git-ignored,
|
|
4
|
+
* never committed — DO NOT EDIT.
|
|
4
5
|
*
|
|
5
6
|
* Registered standardized variation sequences: a base code point followed by the
|
|
6
7
|
* variation selector the UCD registers for it. invisible.mjs preserves such a
|
|
7
8
|
* selector only when the immediately preceding base appears here; every other
|
|
8
9
|
* one is stripped as a hidden-payload byte. Regenerate with
|
|
9
|
-
* `node scripts/gen-standardized-variants.mjs
|
|
10
|
-
* test/invisible-charset.test.mjs fails if this drifts from the pinned UCD.
|
|
10
|
+
* `node scripts/gen-standardized-variants.mjs` (`pnpm install` does).
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export const UNICODE_VERSION = "17.0.0";
|
|
14
14
|
|
|
15
15
|
// The table below is GENERATED UCD data, not hand-written logic. Its correctness
|
|
16
16
|
// is pinned by the SSOT round-trip in test/invisible-charset.test.mjs (re-parse
|
|
17
|
-
// the
|
|
17
|
+
// the pinned file, then assert every pair matches) — a stronger and faster
|
|
18
18
|
// guard than mutating a few hundred numeric literals, so Stryker skips them.
|
|
19
19
|
// Stryker disable all
|
|
20
20
|
/** @type {Array<[number, number]>} [base, selector], sorted by base then selector. */
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GENERATED by scripts/gen-unicode-properties.mjs from the pinned UCD 17.0.0
|
|
2
|
+
* GENERATED by scripts/gen-unicode-properties.mjs from the pinned UCD 17.0.0 at
|
|
3
|
+
* install time; git-ignored, never committed — DO NOT EDIT.
|
|
3
4
|
*
|
|
4
5
|
* The Unicode properties src/invisible.mjs's carve-out reads, PINNED so the
|
|
5
6
|
* carve-out answers the same on every Node whatever its ICU's Unicode version.
|
|
6
|
-
* Regenerate with `node scripts/gen-unicode-properties.mjs
|
|
7
|
-
*
|
|
7
|
+
* Regenerate with `node scripts/gen-unicode-properties.mjs` (`pnpm install`
|
|
8
|
+
* does).
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
export const UNICODE_VERSION = "17.0.0";
|
|
@@ -343,6 +344,337 @@ export const SCRIPT_HANGUL = [
|
|
|
343
344
|
[0xffd2, 0xffd7],
|
|
344
345
|
[0xffda, 0xffdc],
|
|
345
346
|
];
|
|
347
|
+
|
|
348
|
+
/** @type {ReadonlyArray<readonly [number, number]>} */
|
|
349
|
+
export const GENERAL_CATEGORY_MARK = [
|
|
350
|
+
[0x300, 0x36f],
|
|
351
|
+
[0x483, 0x489],
|
|
352
|
+
[0x591, 0x5bd],
|
|
353
|
+
[0x5bf, 0x5bf],
|
|
354
|
+
[0x5c1, 0x5c2],
|
|
355
|
+
[0x5c4, 0x5c5],
|
|
356
|
+
[0x5c7, 0x5c7],
|
|
357
|
+
[0x610, 0x61a],
|
|
358
|
+
[0x64b, 0x65f],
|
|
359
|
+
[0x670, 0x670],
|
|
360
|
+
[0x6d6, 0x6dc],
|
|
361
|
+
[0x6df, 0x6e4],
|
|
362
|
+
[0x6e7, 0x6e8],
|
|
363
|
+
[0x6ea, 0x6ed],
|
|
364
|
+
[0x711, 0x711],
|
|
365
|
+
[0x730, 0x74a],
|
|
366
|
+
[0x7a6, 0x7b0],
|
|
367
|
+
[0x7eb, 0x7f3],
|
|
368
|
+
[0x7fd, 0x7fd],
|
|
369
|
+
[0x816, 0x819],
|
|
370
|
+
[0x81b, 0x823],
|
|
371
|
+
[0x825, 0x827],
|
|
372
|
+
[0x829, 0x82d],
|
|
373
|
+
[0x859, 0x85b],
|
|
374
|
+
[0x897, 0x89f],
|
|
375
|
+
[0x8ca, 0x8e1],
|
|
376
|
+
[0x8e3, 0x903],
|
|
377
|
+
[0x93a, 0x93c],
|
|
378
|
+
[0x93e, 0x94f],
|
|
379
|
+
[0x951, 0x957],
|
|
380
|
+
[0x962, 0x963],
|
|
381
|
+
[0x981, 0x983],
|
|
382
|
+
[0x9bc, 0x9bc],
|
|
383
|
+
[0x9be, 0x9c4],
|
|
384
|
+
[0x9c7, 0x9c8],
|
|
385
|
+
[0x9cb, 0x9cd],
|
|
386
|
+
[0x9d7, 0x9d7],
|
|
387
|
+
[0x9e2, 0x9e3],
|
|
388
|
+
[0x9fe, 0x9fe],
|
|
389
|
+
[0xa01, 0xa03],
|
|
390
|
+
[0xa3c, 0xa3c],
|
|
391
|
+
[0xa3e, 0xa42],
|
|
392
|
+
[0xa47, 0xa48],
|
|
393
|
+
[0xa4b, 0xa4d],
|
|
394
|
+
[0xa51, 0xa51],
|
|
395
|
+
[0xa70, 0xa71],
|
|
396
|
+
[0xa75, 0xa75],
|
|
397
|
+
[0xa81, 0xa83],
|
|
398
|
+
[0xabc, 0xabc],
|
|
399
|
+
[0xabe, 0xac5],
|
|
400
|
+
[0xac7, 0xac9],
|
|
401
|
+
[0xacb, 0xacd],
|
|
402
|
+
[0xae2, 0xae3],
|
|
403
|
+
[0xafa, 0xaff],
|
|
404
|
+
[0xb01, 0xb03],
|
|
405
|
+
[0xb3c, 0xb3c],
|
|
406
|
+
[0xb3e, 0xb44],
|
|
407
|
+
[0xb47, 0xb48],
|
|
408
|
+
[0xb4b, 0xb4d],
|
|
409
|
+
[0xb55, 0xb57],
|
|
410
|
+
[0xb62, 0xb63],
|
|
411
|
+
[0xb82, 0xb82],
|
|
412
|
+
[0xbbe, 0xbc2],
|
|
413
|
+
[0xbc6, 0xbc8],
|
|
414
|
+
[0xbca, 0xbcd],
|
|
415
|
+
[0xbd7, 0xbd7],
|
|
416
|
+
[0xc00, 0xc04],
|
|
417
|
+
[0xc3c, 0xc3c],
|
|
418
|
+
[0xc3e, 0xc44],
|
|
419
|
+
[0xc46, 0xc48],
|
|
420
|
+
[0xc4a, 0xc4d],
|
|
421
|
+
[0xc55, 0xc56],
|
|
422
|
+
[0xc62, 0xc63],
|
|
423
|
+
[0xc81, 0xc83],
|
|
424
|
+
[0xcbc, 0xcbc],
|
|
425
|
+
[0xcbe, 0xcc4],
|
|
426
|
+
[0xcc6, 0xcc8],
|
|
427
|
+
[0xcca, 0xccd],
|
|
428
|
+
[0xcd5, 0xcd6],
|
|
429
|
+
[0xce2, 0xce3],
|
|
430
|
+
[0xcf3, 0xcf3],
|
|
431
|
+
[0xd00, 0xd03],
|
|
432
|
+
[0xd3b, 0xd3c],
|
|
433
|
+
[0xd3e, 0xd44],
|
|
434
|
+
[0xd46, 0xd48],
|
|
435
|
+
[0xd4a, 0xd4d],
|
|
436
|
+
[0xd57, 0xd57],
|
|
437
|
+
[0xd62, 0xd63],
|
|
438
|
+
[0xd81, 0xd83],
|
|
439
|
+
[0xdca, 0xdca],
|
|
440
|
+
[0xdcf, 0xdd4],
|
|
441
|
+
[0xdd6, 0xdd6],
|
|
442
|
+
[0xdd8, 0xddf],
|
|
443
|
+
[0xdf2, 0xdf3],
|
|
444
|
+
[0xe31, 0xe31],
|
|
445
|
+
[0xe34, 0xe3a],
|
|
446
|
+
[0xe47, 0xe4e],
|
|
447
|
+
[0xeb1, 0xeb1],
|
|
448
|
+
[0xeb4, 0xebc],
|
|
449
|
+
[0xec8, 0xece],
|
|
450
|
+
[0xf18, 0xf19],
|
|
451
|
+
[0xf35, 0xf35],
|
|
452
|
+
[0xf37, 0xf37],
|
|
453
|
+
[0xf39, 0xf39],
|
|
454
|
+
[0xf3e, 0xf3f],
|
|
455
|
+
[0xf71, 0xf84],
|
|
456
|
+
[0xf86, 0xf87],
|
|
457
|
+
[0xf8d, 0xf97],
|
|
458
|
+
[0xf99, 0xfbc],
|
|
459
|
+
[0xfc6, 0xfc6],
|
|
460
|
+
[0x102b, 0x103e],
|
|
461
|
+
[0x1056, 0x1059],
|
|
462
|
+
[0x105e, 0x1060],
|
|
463
|
+
[0x1062, 0x1064],
|
|
464
|
+
[0x1067, 0x106d],
|
|
465
|
+
[0x1071, 0x1074],
|
|
466
|
+
[0x1082, 0x108d],
|
|
467
|
+
[0x108f, 0x108f],
|
|
468
|
+
[0x109a, 0x109d],
|
|
469
|
+
[0x135d, 0x135f],
|
|
470
|
+
[0x1712, 0x1715],
|
|
471
|
+
[0x1732, 0x1734],
|
|
472
|
+
[0x1752, 0x1753],
|
|
473
|
+
[0x1772, 0x1773],
|
|
474
|
+
[0x17b4, 0x17d3],
|
|
475
|
+
[0x17dd, 0x17dd],
|
|
476
|
+
[0x180b, 0x180d],
|
|
477
|
+
[0x180f, 0x180f],
|
|
478
|
+
[0x1885, 0x1886],
|
|
479
|
+
[0x18a9, 0x18a9],
|
|
480
|
+
[0x1920, 0x192b],
|
|
481
|
+
[0x1930, 0x193b],
|
|
482
|
+
[0x1a17, 0x1a1b],
|
|
483
|
+
[0x1a55, 0x1a5e],
|
|
484
|
+
[0x1a60, 0x1a7c],
|
|
485
|
+
[0x1a7f, 0x1a7f],
|
|
486
|
+
[0x1ab0, 0x1add],
|
|
487
|
+
[0x1ae0, 0x1aeb],
|
|
488
|
+
[0x1b00, 0x1b04],
|
|
489
|
+
[0x1b34, 0x1b44],
|
|
490
|
+
[0x1b6b, 0x1b73],
|
|
491
|
+
[0x1b80, 0x1b82],
|
|
492
|
+
[0x1ba1, 0x1bad],
|
|
493
|
+
[0x1be6, 0x1bf3],
|
|
494
|
+
[0x1c24, 0x1c37],
|
|
495
|
+
[0x1cd0, 0x1cd2],
|
|
496
|
+
[0x1cd4, 0x1ce8],
|
|
497
|
+
[0x1ced, 0x1ced],
|
|
498
|
+
[0x1cf4, 0x1cf4],
|
|
499
|
+
[0x1cf7, 0x1cf9],
|
|
500
|
+
[0x1dc0, 0x1dff],
|
|
501
|
+
[0x20d0, 0x20f0],
|
|
502
|
+
[0x2cef, 0x2cf1],
|
|
503
|
+
[0x2d7f, 0x2d7f],
|
|
504
|
+
[0x2de0, 0x2dff],
|
|
505
|
+
[0x302a, 0x302f],
|
|
506
|
+
[0x3099, 0x309a],
|
|
507
|
+
[0xa66f, 0xa672],
|
|
508
|
+
[0xa674, 0xa67d],
|
|
509
|
+
[0xa69e, 0xa69f],
|
|
510
|
+
[0xa6f0, 0xa6f1],
|
|
511
|
+
[0xa802, 0xa802],
|
|
512
|
+
[0xa806, 0xa806],
|
|
513
|
+
[0xa80b, 0xa80b],
|
|
514
|
+
[0xa823, 0xa827],
|
|
515
|
+
[0xa82c, 0xa82c],
|
|
516
|
+
[0xa880, 0xa881],
|
|
517
|
+
[0xa8b4, 0xa8c5],
|
|
518
|
+
[0xa8e0, 0xa8f1],
|
|
519
|
+
[0xa8ff, 0xa8ff],
|
|
520
|
+
[0xa926, 0xa92d],
|
|
521
|
+
[0xa947, 0xa953],
|
|
522
|
+
[0xa980, 0xa983],
|
|
523
|
+
[0xa9b3, 0xa9c0],
|
|
524
|
+
[0xa9e5, 0xa9e5],
|
|
525
|
+
[0xaa29, 0xaa36],
|
|
526
|
+
[0xaa43, 0xaa43],
|
|
527
|
+
[0xaa4c, 0xaa4d],
|
|
528
|
+
[0xaa7b, 0xaa7d],
|
|
529
|
+
[0xaab0, 0xaab0],
|
|
530
|
+
[0xaab2, 0xaab4],
|
|
531
|
+
[0xaab7, 0xaab8],
|
|
532
|
+
[0xaabe, 0xaabf],
|
|
533
|
+
[0xaac1, 0xaac1],
|
|
534
|
+
[0xaaeb, 0xaaef],
|
|
535
|
+
[0xaaf5, 0xaaf6],
|
|
536
|
+
[0xabe3, 0xabea],
|
|
537
|
+
[0xabec, 0xabed],
|
|
538
|
+
[0xfb1e, 0xfb1e],
|
|
539
|
+
[0xfe00, 0xfe0f],
|
|
540
|
+
[0xfe20, 0xfe2f],
|
|
541
|
+
[0x101fd, 0x101fd],
|
|
542
|
+
[0x102e0, 0x102e0],
|
|
543
|
+
[0x10376, 0x1037a],
|
|
544
|
+
[0x10a01, 0x10a03],
|
|
545
|
+
[0x10a05, 0x10a06],
|
|
546
|
+
[0x10a0c, 0x10a0f],
|
|
547
|
+
[0x10a38, 0x10a3a],
|
|
548
|
+
[0x10a3f, 0x10a3f],
|
|
549
|
+
[0x10ae5, 0x10ae6],
|
|
550
|
+
[0x10d24, 0x10d27],
|
|
551
|
+
[0x10d69, 0x10d6d],
|
|
552
|
+
[0x10eab, 0x10eac],
|
|
553
|
+
[0x10efa, 0x10eff],
|
|
554
|
+
[0x10f46, 0x10f50],
|
|
555
|
+
[0x10f82, 0x10f85],
|
|
556
|
+
[0x11000, 0x11002],
|
|
557
|
+
[0x11038, 0x11046],
|
|
558
|
+
[0x11070, 0x11070],
|
|
559
|
+
[0x11073, 0x11074],
|
|
560
|
+
[0x1107f, 0x11082],
|
|
561
|
+
[0x110b0, 0x110ba],
|
|
562
|
+
[0x110c2, 0x110c2],
|
|
563
|
+
[0x11100, 0x11102],
|
|
564
|
+
[0x11127, 0x11134],
|
|
565
|
+
[0x11145, 0x11146],
|
|
566
|
+
[0x11173, 0x11173],
|
|
567
|
+
[0x11180, 0x11182],
|
|
568
|
+
[0x111b3, 0x111c0],
|
|
569
|
+
[0x111c9, 0x111cc],
|
|
570
|
+
[0x111ce, 0x111cf],
|
|
571
|
+
[0x1122c, 0x11237],
|
|
572
|
+
[0x1123e, 0x1123e],
|
|
573
|
+
[0x11241, 0x11241],
|
|
574
|
+
[0x112df, 0x112ea],
|
|
575
|
+
[0x11300, 0x11303],
|
|
576
|
+
[0x1133b, 0x1133c],
|
|
577
|
+
[0x1133e, 0x11344],
|
|
578
|
+
[0x11347, 0x11348],
|
|
579
|
+
[0x1134b, 0x1134d],
|
|
580
|
+
[0x11357, 0x11357],
|
|
581
|
+
[0x11362, 0x11363],
|
|
582
|
+
[0x11366, 0x1136c],
|
|
583
|
+
[0x11370, 0x11374],
|
|
584
|
+
[0x113b8, 0x113c0],
|
|
585
|
+
[0x113c2, 0x113c2],
|
|
586
|
+
[0x113c5, 0x113c5],
|
|
587
|
+
[0x113c7, 0x113ca],
|
|
588
|
+
[0x113cc, 0x113d0],
|
|
589
|
+
[0x113d2, 0x113d2],
|
|
590
|
+
[0x113e1, 0x113e2],
|
|
591
|
+
[0x11435, 0x11446],
|
|
592
|
+
[0x1145e, 0x1145e],
|
|
593
|
+
[0x114b0, 0x114c3],
|
|
594
|
+
[0x115af, 0x115b5],
|
|
595
|
+
[0x115b8, 0x115c0],
|
|
596
|
+
[0x115dc, 0x115dd],
|
|
597
|
+
[0x11630, 0x11640],
|
|
598
|
+
[0x116ab, 0x116b7],
|
|
599
|
+
[0x1171d, 0x1172b],
|
|
600
|
+
[0x1182c, 0x1183a],
|
|
601
|
+
[0x11930, 0x11935],
|
|
602
|
+
[0x11937, 0x11938],
|
|
603
|
+
[0x1193b, 0x1193e],
|
|
604
|
+
[0x11940, 0x11940],
|
|
605
|
+
[0x11942, 0x11943],
|
|
606
|
+
[0x119d1, 0x119d7],
|
|
607
|
+
[0x119da, 0x119e0],
|
|
608
|
+
[0x119e4, 0x119e4],
|
|
609
|
+
[0x11a01, 0x11a0a],
|
|
610
|
+
[0x11a33, 0x11a39],
|
|
611
|
+
[0x11a3b, 0x11a3e],
|
|
612
|
+
[0x11a47, 0x11a47],
|
|
613
|
+
[0x11a51, 0x11a5b],
|
|
614
|
+
[0x11a8a, 0x11a99],
|
|
615
|
+
[0x11b60, 0x11b67],
|
|
616
|
+
[0x11c2f, 0x11c36],
|
|
617
|
+
[0x11c38, 0x11c3f],
|
|
618
|
+
[0x11c92, 0x11ca7],
|
|
619
|
+
[0x11ca9, 0x11cb6],
|
|
620
|
+
[0x11d31, 0x11d36],
|
|
621
|
+
[0x11d3a, 0x11d3a],
|
|
622
|
+
[0x11d3c, 0x11d3d],
|
|
623
|
+
[0x11d3f, 0x11d45],
|
|
624
|
+
[0x11d47, 0x11d47],
|
|
625
|
+
[0x11d8a, 0x11d8e],
|
|
626
|
+
[0x11d90, 0x11d91],
|
|
627
|
+
[0x11d93, 0x11d97],
|
|
628
|
+
[0x11ef3, 0x11ef6],
|
|
629
|
+
[0x11f00, 0x11f01],
|
|
630
|
+
[0x11f03, 0x11f03],
|
|
631
|
+
[0x11f34, 0x11f3a],
|
|
632
|
+
[0x11f3e, 0x11f42],
|
|
633
|
+
[0x11f5a, 0x11f5a],
|
|
634
|
+
[0x13440, 0x13440],
|
|
635
|
+
[0x13447, 0x13455],
|
|
636
|
+
[0x1611e, 0x1612f],
|
|
637
|
+
[0x16af0, 0x16af4],
|
|
638
|
+
[0x16b30, 0x16b36],
|
|
639
|
+
[0x16f4f, 0x16f4f],
|
|
640
|
+
[0x16f51, 0x16f87],
|
|
641
|
+
[0x16f8f, 0x16f92],
|
|
642
|
+
[0x16fe4, 0x16fe4],
|
|
643
|
+
[0x16ff0, 0x16ff1],
|
|
644
|
+
[0x1bc9d, 0x1bc9e],
|
|
645
|
+
[0x1cf00, 0x1cf2d],
|
|
646
|
+
[0x1cf30, 0x1cf46],
|
|
647
|
+
[0x1d165, 0x1d169],
|
|
648
|
+
[0x1d16d, 0x1d172],
|
|
649
|
+
[0x1d17b, 0x1d182],
|
|
650
|
+
[0x1d185, 0x1d18b],
|
|
651
|
+
[0x1d1aa, 0x1d1ad],
|
|
652
|
+
[0x1d242, 0x1d244],
|
|
653
|
+
[0x1da00, 0x1da36],
|
|
654
|
+
[0x1da3b, 0x1da6c],
|
|
655
|
+
[0x1da75, 0x1da75],
|
|
656
|
+
[0x1da84, 0x1da84],
|
|
657
|
+
[0x1da9b, 0x1da9f],
|
|
658
|
+
[0x1daa1, 0x1daaf],
|
|
659
|
+
[0x1e000, 0x1e006],
|
|
660
|
+
[0x1e008, 0x1e018],
|
|
661
|
+
[0x1e01b, 0x1e021],
|
|
662
|
+
[0x1e023, 0x1e024],
|
|
663
|
+
[0x1e026, 0x1e02a],
|
|
664
|
+
[0x1e08f, 0x1e08f],
|
|
665
|
+
[0x1e130, 0x1e136],
|
|
666
|
+
[0x1e2ae, 0x1e2ae],
|
|
667
|
+
[0x1e2ec, 0x1e2ef],
|
|
668
|
+
[0x1e4ec, 0x1e4ef],
|
|
669
|
+
[0x1e5ee, 0x1e5ef],
|
|
670
|
+
[0x1e6e3, 0x1e6e3],
|
|
671
|
+
[0x1e6e6, 0x1e6e6],
|
|
672
|
+
[0x1e6ee, 0x1e6ef],
|
|
673
|
+
[0x1e6f5, 0x1e6f5],
|
|
674
|
+
[0x1e8d0, 0x1e8d6],
|
|
675
|
+
[0x1e944, 0x1e94a],
|
|
676
|
+
[0xe0100, 0xe01ef],
|
|
677
|
+
];
|
|
346
678
|
// Stryker restore all
|
|
347
679
|
|
|
348
680
|
/**
|
package/src/view-map.mjs
CHANGED
|
@@ -220,6 +220,8 @@ export function overlapAwareCount(haystack, needle) {
|
|
|
220
220
|
* The character runs Layer 1 deleted, located by greedy subsequence alignment
|
|
221
221
|
* (stripping only deletes, so `cleaned` is always a subsequence of `content`).
|
|
222
222
|
* Throws if the subsequence property does not hold — the caller fails closed.
|
|
223
|
+
* Aligned per CODE POINT (Layer 1 deletes whole ones): a code-unit walk matches
|
|
224
|
+
* U+1D173's high surrogate against U+1D11E's and splits both. Offsets stay UTF-16.
|
|
223
225
|
* @param {string} content disk bytes
|
|
224
226
|
* @param {string} cleaned Layer-1 view of the same bytes
|
|
225
227
|
* @returns {{start: number, deleted: string}[]}
|
|
@@ -228,15 +230,15 @@ export function alignDeletions(content, cleaned) {
|
|
|
228
230
|
const deletions = [];
|
|
229
231
|
let run = "";
|
|
230
232
|
let ci = 0;
|
|
231
|
-
for (
|
|
232
|
-
if (ci < cleaned.length &&
|
|
233
|
+
for (const ch of content) {
|
|
234
|
+
if (ci < cleaned.length && cleaned.startsWith(ch, ci)) {
|
|
233
235
|
if (run) {
|
|
234
236
|
deletions.push({ start: ci, deleted: run });
|
|
235
237
|
run = "";
|
|
236
238
|
}
|
|
237
|
-
ci
|
|
239
|
+
ci += ch.length;
|
|
238
240
|
} else {
|
|
239
|
-
run +=
|
|
241
|
+
run += ch;
|
|
240
242
|
}
|
|
241
243
|
}
|
|
242
244
|
if (ci !== cleaned.length)
|
package/src/warnings.mjs
CHANGED
|
@@ -68,6 +68,13 @@ export function describeHtmlSanitized(removed) {
|
|
|
68
68
|
export const HTML_UNPARSEABLE_WARNING =
|
|
69
69
|
"HTML unparseable — the entire output was withheld behind a placeholder; nothing was spliced";
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* The Layer-3 warning when the URL scan overflowed the stack. It names no URL
|
|
73
|
+
* (none was found), yet stays a warning: unread is not vetted.
|
|
74
|
+
*/
|
|
75
|
+
export const UNSCANNABLE_WARNING =
|
|
76
|
+
"Input too deeply nested to scan for exfil URLs or look-alike hosts — any URL in it is unvetted; do not fetch, relay, or embed it";
|
|
77
|
+
|
|
71
78
|
/**
|
|
72
79
|
* Full warning for Layer 2's preserved-but-reported content (scripting and
|
|
73
80
|
* resource tags, data: URIs), or "" when there is nothing to report. Callers
|
package/types/cf-charset.d.mts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GENERATED by scripts/gen-
|
|
3
|
-
* (General_Category=Cf, Unicode 17.0.0)
|
|
2
|
+
* GENERATED by scripts/gen-cf-charset.mjs from the pinned UCD
|
|
3
|
+
* (General_Category=Cf, Unicode 17.0.0) at install, pack and build
|
|
4
|
+
* time; git-ignored, never committed — DO NOT EDIT.
|
|
4
5
|
*
|
|
5
6
|
* The general-category Cf code points, PINNED at generation time. invisible.mjs
|
|
6
7
|
* strips exactly this set instead of asking the runtime for Cf, and the Python port
|
|
7
8
|
* reads the SAME set from data/invisible-charset.json's `cf_codepoints`, so both
|
|
8
9
|
* layers strip an identical Cf set regardless of each runtime's own Unicode
|
|
9
|
-
* version. Regenerate with `node scripts/gen-
|
|
10
|
-
*
|
|
10
|
+
* version. Regenerate with `node scripts/gen-cf-charset.mjs` (`pnpm install`
|
|
11
|
+
* does).
|
|
11
12
|
*/
|
|
12
13
|
export const UNICODE_VERSION: "17.0.0";
|
|
13
14
|
/** @type {readonly number[]} Sorted ascending. */
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The redactor socket path: one per user, shared by every session of that user
|
|
3
|
+
* (the daemon redacts each REQUESTER's env secrets). The daemon binds it 0600
|
|
4
|
+
* under a 0700 dir AFTER priming, so its existence means "ready". In order:
|
|
5
|
+
*
|
|
6
|
+
* 1. `_AGENT_SANITIZER_REDACTOR_SOCKET` — explicit override.
|
|
7
|
+
* 2. `$XDG_RUNTIME_DIR`, then `$CLAUDE_PLUGIN_DATA` — per-user directories no
|
|
8
|
+
* other uid can write, so a co-tenant cannot pre-create the socket dir under
|
|
9
|
+
* them. Taken only if isPrivateRoot passes and the path fits sun_path.
|
|
10
|
+
* 3. `<tmpdir>/agent-sanitizer-redactor-<uid>` — on a shared /tmp a co-tenant
|
|
11
|
+
* can still pre-create it; the daemon then refuses to serve and the client
|
|
12
|
+
* refuses to connect (classifySocket), costing availability, never a secret.
|
|
13
|
+
* @param {NodeJS.ProcessEnv} env
|
|
14
|
+
* @param {number | null} uid null where the platform has no uid model, which
|
|
15
|
+
* trusts no root (see {@link isPrivateDir})
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
export function resolveSocketPath(env: NodeJS.ProcessEnv, uid: number | null): string;
|
|
1
19
|
/**
|
|
2
20
|
* The shape the redactor returns: plain mode `{text, found}`, map mode
|
|
3
21
|
* `{text, pairs, found}` or `{unmappable}`. All fields optional so a consumer
|
|
@@ -77,35 +77,25 @@ export function sanitizeText(text: string, toolName: string, deadline?: {
|
|
|
77
77
|
}>;
|
|
78
78
|
}>;
|
|
79
79
|
/**
|
|
80
|
-
* Sanitize every string leaf of a tool-output value
|
|
81
|
-
*
|
|
82
|
-
* isImage}`), and the
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* across leaves.
|
|
89
|
-
* `sgrNote` is the OR across leaves: true when some leaf came back note-only.
|
|
90
|
-
* `reveals` accumulates each leaf's pre-Layer-2 text (when the HTML splice
|
|
91
|
-
* removed something) for the orchestrator to persist, and `notes` the leaves'
|
|
92
|
-
* NOTE-severity findings — same mutated-accumulator shape as `warnings`.
|
|
93
|
-
* `splices` accumulates each leaf's Layer-2 placeholder→original pairs (the
|
|
94
|
-
* per-key twin of `reveals`, already vetted by the seam) for the orchestrator's
|
|
95
|
-
* span persistence — same mutated-accumulator shape again.
|
|
80
|
+
* Sanitize every string leaf AND object key of a tool-output value under this
|
|
81
|
+
* hook's per-tool policy, preserving its shape. Built-in tools return
|
|
82
|
+
* structured objects (Bash: `{stdout, stderr, interrupted, isImage}`), and the
|
|
83
|
+
* harness ignores an `updatedToolOutput` whose shape does not match the tool's
|
|
84
|
+
* schema — showing the raw output instead. The walk, its key-collision
|
|
85
|
+
* withholding and its depth/cycle guards are the engine's sanitizeValueWith,
|
|
86
|
+
* so this hook and the library cannot disagree about a value's strings.
|
|
87
|
+
* `warnings`, `reveals`, `notes` and `splices` accumulate across strings.
|
|
96
88
|
* @param {any} value
|
|
97
89
|
* @param {string} toolName
|
|
98
90
|
* @param {string[]} warnings
|
|
99
91
|
* @param {string[]} [reveals]
|
|
100
92
|
* @param {{remainingMs: () => number}} [deadline] shared wall-clock budget across
|
|
101
|
-
* every
|
|
93
|
+
* every string of this value (created once by the top-level caller)
|
|
102
94
|
* @param {SanitizeExtensions} [ext]
|
|
103
95
|
* @param {string[]} [notes] appended last so an existing caller's positional
|
|
104
96
|
* arguments keep their meaning
|
|
105
97
|
* @param {Array<{ placeholder: string, original: string }>} [splices] appended
|
|
106
98
|
* after `notes` for the same positional-compatibility reason
|
|
107
|
-
* @param {string} [path] dotted location of `value` within the tool output,
|
|
108
|
-
* used only to name a key collision's location in its warning
|
|
109
99
|
* @param {boolean} [secretsOn] the secret opt-in (see {@link sanitizeText})
|
|
110
100
|
* @returns {Promise<{ value: any, modified: boolean, sgrNote: boolean }>}
|
|
111
101
|
*/
|
|
@@ -114,19 +104,11 @@ export function sanitizeValue(value: any, toolName: string, warnings: string[],
|
|
|
114
104
|
}, ext?: SanitizeExtensions, notes?: string[], splices?: Array<{
|
|
115
105
|
placeholder: string;
|
|
116
106
|
original: string;
|
|
117
|
-
}>,
|
|
107
|
+
}>, secretsOn?: boolean): Promise<{
|
|
118
108
|
value: any;
|
|
119
109
|
modified: boolean;
|
|
120
110
|
sgrNote: boolean;
|
|
121
111
|
}>;
|
|
122
|
-
/**
|
|
123
|
-
* The warning for a post-sanitization key collision, naming where it sits.
|
|
124
|
-
* Exported so tests assert by reference rather than re-typing the prose.
|
|
125
|
-
* @param {string} name the collapsed-to name
|
|
126
|
-
* @param {string} path dotted location of the owning object ("" = top level)
|
|
127
|
-
* @returns {string}
|
|
128
|
-
*/
|
|
129
|
-
export function collisionWarning(name: string, path: string): string;
|
|
130
112
|
/**
|
|
131
113
|
* Compose the model-facing additionalContext line for a sanitized/flagged tool
|
|
132
114
|
* output. The seam (composeContextSeam) owns the prefix + warning join; this
|
|
@@ -139,9 +121,10 @@ export function collisionWarning(name: string, path: string): string;
|
|
|
139
121
|
* @param {boolean} modified output bytes were changed (vs. flagged only)
|
|
140
122
|
* @param {string[]} warnings
|
|
141
123
|
* @param {string} toolName
|
|
124
|
+
* @param {string[]} [notes] appended after the warnings (see composeContextSeam)
|
|
142
125
|
* @returns {string}
|
|
143
126
|
*/
|
|
144
|
-
export function composeContext(modified: boolean, warnings: string[], toolName: string): string;
|
|
127
|
+
export function composeContext(modified: boolean, warnings: string[], toolName: string, notes?: string[]): string;
|
|
145
128
|
/**
|
|
146
129
|
* Fail-closed replacement: a shape-matching placeholder for the parsed tool
|
|
147
130
|
* output, or the bare `message` when stdin never parsed or carried no
|
|
@@ -276,8 +259,9 @@ export const SECRET_HINT_EXT: RegExp;
|
|
|
276
259
|
export const describeRemoved: typeof import("agent-sanitizer/output").describeRemoved;
|
|
277
260
|
export const describeWarned: typeof import("agent-sanitizer/output").describeWarned;
|
|
278
261
|
export const suppressToolOutput: typeof import("agent-sanitizer/output").suppressToolOutput;
|
|
262
|
+
export const COLLISION_WITHHELD_MESSAGE: "[WITHHELD — this field's name collided with another after sanitization]";
|
|
263
|
+
export const collisionWarning: typeof import("agent-sanitizer/output").collisionWarning;
|
|
279
264
|
export const REVEAL_WITHHELD_WARNING: string;
|
|
280
|
-
export const COLLISION_WITHHELD_MESSAGE: "[WITHHELD \u2014 this field's name collided with another after sanitization]";
|
|
281
265
|
export const ON_DISK_PLACEHOLDER_WARNING: string;
|
|
282
266
|
/**
|
|
283
267
|
* Host-supplied extensions to this hook, threaded from {@link cliMain} down to
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
* The two tiers are evidential strength, not attack class:
|
|
7
7
|
*
|
|
8
8
|
* WARNING — the WHOLE label skeletons to ASCII, so it reads as an ASCII name
|
|
9
|
-
* outright,
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* outright, no glyph in it survives as evidence of a real foreign word, and at
|
|
10
|
+
* least one glyph is a genuine pretender (see isAsciiPretender).
|
|
11
|
+
* NOTE — the label skeletons to ASCII only through letters of a real Latin
|
|
12
|
+
* orthography (Turkish `altın` is a word, not a disguise), or it carries a
|
|
13
|
+
* cross-script confusable but keeps an unmapped glyph, so it reads as no ASCII
|
|
14
|
+
* name — the "unmapped glyph spliced in" shape, and also what an ordinary word
|
|
15
|
+
* with one look-alike letter produces. Thin evidence, so the finding is quiet.
|
|
15
16
|
* @param {string} label a single DNS label, already decoded from punycode
|
|
16
17
|
* @returns {string | null} the label's severity, or null when it is not pretending
|
|
17
18
|
*/
|
package/types/confusables.d.mts
CHANGED
|
@@ -26,6 +26,18 @@ export function scopeFor(tool: string, fields?: Record<string, string[]>): {
|
|
|
26
26
|
* @returns {boolean}
|
|
27
27
|
*/
|
|
28
28
|
export function hasNonAscii(value: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* True when `glyph` holds a non-ASCII code point that is neither a combining
|
|
31
|
+
* mark nor a letter of a real Latin-script orthography. THE predicate both the
|
|
32
|
+
* host rule's WARNING tier and the input fold gate on, so they cannot disagree.
|
|
33
|
+
* Turkish `ı`, Spanish `í`, Polish `ł` are a word's own letters (`altın.com`,
|
|
34
|
+
* `día.txt`), and flagging them is the worse failure; a cross-script glyph
|
|
35
|
+
* (Cyrillic `а`), an IPA/small-capital one (`ɡ`, `ᴀ`) or anything NFKC folds
|
|
36
|
+
* to ASCII (`a`, `fi`) stays a pretender.
|
|
37
|
+
* @param {string} glyph one or more code points
|
|
38
|
+
* @returns {boolean}
|
|
39
|
+
*/
|
|
40
|
+
export function isAsciiPretender(glyph: string): boolean;
|
|
29
41
|
/**
|
|
30
42
|
* Model-facing note naming the fields whose confusables were folded.
|
|
31
43
|
* @param {string[]} normalized
|