diff --git a/src/extensions/SafeClipboard.hostileThrow.test.ts b/src/extensions/SafeClipboard.hostileThrow.test.ts
new file mode 100644
index 00000000..6c9ea33f
--- /dev/null
+++ b/src/extensions/SafeClipboard.hostileThrow.test.ts
@@ -0,0 +1,50 @@
+import { describe, expect, it, vi } from 'vitest';
+
+import {
+ isClipboardSanitizationError,
+ sanitizeRichClipboardHtml,
+ type ClipboardConfig,
+} from './SafeClipboard.js';
+
+/**
+ * Exercise the direct sanitizer boundary with a hostile configuration failure.
+ * Unknown thrown values must be normalized without prototype inspection.
+ */
+describe('SafeClipboard sanitizer hostile thrown-value containment', () => {
+ it('rejects primitive values without consulting the WeakSet', () => {
+ expect(isClipboardSanitizationError('private primitive sentinel')).toBe(false);
+ expect(isClipboardSanitizationError(1)).toBe(false);
+ expect(isClipboardSanitizationError(null)).toBe(false);
+ });
+
+ it('normalizes hostile configuration failures without prototype inspection', () => {
+ const privateSentinel = new Error('private sanitizer prototype sentinel');
+ const getPrototypeOf = vi.fn(() => {
+ throw privateSentinel;
+ });
+ const hostileThrownValue = new Proxy(Object.create(null) as object, {
+ getPrototypeOf,
+ });
+ const hostileConfig = new Proxy(Object.create(null) as ClipboardConfig, {
+ ownKeys() {
+ throw hostileThrownValue;
+ },
+ });
+
+ let observed: unknown;
+ try {
+ sanitizeRichClipboardHtml('
private source
', hostileConfig, document);
+ } catch (error) {
+ observed = error;
+ }
+
+ expect(getPrototypeOf).not.toHaveBeenCalled();
+ expect(observed).toEqual(
+ expect.objectContaining({
+ name: 'ClipboardSanitizationError',
+ code: 'invalid_configuration',
+ message: 'Rich clipboard configuration is invalid.',
+ }),
+ );
+ });
+});
diff --git a/src/extensions/SafeClipboard.ts b/src/extensions/SafeClipboard.ts
index a3eaef4c..5e4aef8c 100644
--- a/src/extensions/SafeClipboard.ts
+++ b/src/extensions/SafeClipboard.ts
@@ -58,6 +58,8 @@ const ERROR_MESSAGES: Readonly> =
invalid_html: 'Rich clipboard HTML could not be sanitized.',
});
+const CLIPBOARD_SANITIZATION_ERRORS = new WeakSet