Commit 0fee85f
security(git-id-switcher): introduce SanitizedHtml branded type for buildDocumentHtml content (#455)
Promote the `content` parameter of `buildDocumentHtml` from a plain
`string` (contract-by-docstring) to a `SanitizedHtml` branded string type
so that the trust boundary between the markdown sanitizer and the webview
HTML shell is enforced at compile time. Previously, a future caller could
pass an unsanitized `string` and the only remaining defence was CSP —
which does not block `<img onerror>` or `javascript:` URLs outside the
link interceptor path.
Changes:
- htmlTemplates.ts: export `SanitizedHtml = string & { readonly __brand }`
and retype `buildDocumentHtml(content: SanitizedHtml)`.
- documentationInternal.ts: `renderMarkdown` now returns `SanitizedHtml`,
with a single sanctioned `as SanitizedHtml` cast at its return site
(the sole origin of the brand in production code). Type-only import
from htmlTemplates to avoid promoting the existing one-way runtime
import edge into a circular dependency.
- webview.ts: `getDocumentHtml` wrapper signature upgraded and type
re-exported so downstream consumers inherit the constraint.
- htmlTemplates.test.ts: isolated, documented `asSanitizedHtml` test
helper for structural tests that exercise the shell rather than the
sanitizer (renderMarkdown has its own dedicated coverage in
documentation.test.ts).
Security review (delegated, security-engineer persona): no Critical or
Medium findings. Single Low finding (circular-import fragility) folded
in as an inline comment on the type-only import.
tsc, eslint (--max-warnings=0), and test:coverage all pass;
htmlTemplates.ts and documentationInternal.ts retain 100% statement
coverage.
🖥️ IDE: [VS Code](https://code.visualstudio.com/)
🔌 Extension: [Claude Code](https://claude.ai/download)
Model-Raw: claude-opus-4-6
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 2adbb54 commit 0fee85f
4 files changed
Lines changed: 64 additions & 22 deletions
File tree
- extensions/git-id-switcher/src
- test
- ui
Lines changed: 23 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
45 | 56 | | |
46 | 57 | | |
47 | 58 | | |
| |||
342 | 353 | | |
343 | 354 | | |
344 | 355 | | |
345 | | - | |
| 356 | + | |
346 | 357 | | |
347 | 358 | | |
348 | 359 | | |
| |||
362 | 373 | | |
363 | 374 | | |
364 | 375 | | |
365 | | - | |
| 376 | + | |
366 | 377 | | |
367 | 378 | | |
368 | 379 | | |
| |||
443 | 454 | | |
444 | 455 | | |
445 | 456 | | |
446 | | - | |
| 457 | + | |
447 | 458 | | |
448 | 459 | | |
449 | 460 | | |
| |||
490 | 501 | | |
491 | 502 | | |
492 | 503 | | |
493 | | - | |
| 504 | + | |
494 | 505 | | |
495 | 506 | | |
496 | 507 | | |
| |||
512 | 523 | | |
513 | 524 | | |
514 | 525 | | |
515 | | - | |
| 526 | + | |
516 | 527 | | |
517 | 528 | | |
518 | 529 | | |
| |||
567 | 578 | | |
568 | 579 | | |
569 | 580 | | |
570 | | - | |
| 581 | + | |
571 | 582 | | |
572 | 583 | | |
573 | 584 | | |
| |||
603 | 614 | | |
604 | 615 | | |
605 | 616 | | |
606 | | - | |
| 617 | + | |
607 | 618 | | |
608 | 619 | | |
609 | 620 | | |
| |||
650 | 661 | | |
651 | 662 | | |
652 | 663 | | |
653 | | - | |
| 664 | + | |
654 | 665 | | |
655 | 666 | | |
656 | 667 | | |
| |||
665 | 676 | | |
666 | 677 | | |
667 | 678 | | |
668 | | - | |
| 679 | + | |
669 | 680 | | |
670 | 681 | | |
671 | 682 | | |
| |||
696 | 707 | | |
697 | 708 | | |
698 | 709 | | |
699 | | - | |
| 710 | + | |
700 | 711 | | |
701 | 712 | | |
702 | 713 | | |
| |||
851 | 862 | | |
852 | 863 | | |
853 | 864 | | |
854 | | - | |
| 865 | + | |
855 | 866 | | |
856 | 867 | | |
857 | 868 | | |
858 | 869 | | |
859 | 870 | | |
860 | 871 | | |
861 | 872 | | |
862 | | - | |
| 873 | + | |
863 | 874 | | |
864 | 875 | | |
865 | 876 | | |
| |||
Lines changed: 13 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
12 | 17 | | |
13 | 18 | | |
14 | 19 | | |
| |||
320 | 325 | | |
321 | 326 | | |
322 | 327 | | |
323 | | - | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
324 | 332 | | |
325 | | - | |
| 333 | + | |
326 | 334 | | |
327 | 335 | | |
328 | 336 | | |
| |||
445 | 453 | | |
446 | 454 | | |
447 | 455 | | |
448 | | - | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
449 | 459 | | |
450 | 460 | | |
451 | 461 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
23 | 41 | | |
24 | 42 | | |
25 | 43 | | |
| |||
229 | 247 | | |
230 | 248 | | |
231 | 249 | | |
232 | | - | |
233 | | - | |
234 | | - | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
235 | 254 | | |
236 | | - | |
| 255 | + | |
| 256 | + | |
237 | 257 | | |
238 | 258 | | |
239 | 259 | | |
| |||
242 | 262 | | |
243 | 263 | | |
244 | 264 | | |
245 | | - | |
| 265 | + | |
246 | 266 | | |
247 | 267 | | |
248 | 268 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
26 | | - | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
72 | | - | |
| 73 | + | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
0 commit comments