]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): ensure iframe sandbox is handled as an attribute to prevent uninten...
authorclay jenson <krystalnumber@gmail.com>
Wed, 5 Nov 2025 08:53:58 +0000 (16:53 +0800)
committerGitHub <noreply@github.com>
Wed, 5 Nov 2025 08:53:58 +0000 (16:53 +0800)
close #13946

packages/runtime-dom/__tests__/patchAttrs.spec.ts
packages/runtime-dom/src/patchProp.ts

index 393b685b0e9b3fbe7b3d7022baea0afb5f71ac33..d181a1b038b5b2f269f0f7d5cd86393a0342d28a 100644 (file)
@@ -88,4 +88,38 @@ describe('runtime-dom: attrs patching', () => {
     expect(el2.dataset.test).toBe(undefined)
     expect(testvalue).toBe(obj)
   })
+
+  // #13946
+  test('sandbox should be handled as attribute even if property exists', () => {
+    const iframe = document.createElement('iframe') as any
+    let propSetCount = 0
+    // simulate sandbox property in jsdom environment
+    Object.defineProperty(iframe, 'sandbox', {
+      configurable: true,
+      enumerable: true,
+      get() {
+        return this._sandbox
+      },
+      set(v) {
+        propSetCount++
+        this._sandbox = v
+      },
+    })
+
+    patchProp(iframe, 'sandbox', null, 'allow-scripts')
+    expect(iframe.getAttribute('sandbox')).toBe('allow-scripts')
+    expect(propSetCount).toBe(0)
+
+    patchProp(iframe, 'sandbox', 'allow-scripts', null)
+    expect(iframe.hasAttribute('sandbox')).toBe(false)
+    expect(iframe.getAttribute('sandbox')).toBe(null)
+    expect(propSetCount).toBe(0)
+
+    patchProp(iframe, 'sandbox', null, '')
+    expect(iframe.getAttribute('sandbox')).toBe('')
+    expect(iframe.hasAttribute('sandbox')).toBe(true)
+    expect(propSetCount).toBe(0)
+
+    delete iframe.sandbox
+  })
 })
index 27174ddf62460238ef59cbbd2a1d7a3020b6fe28..74b5774ec9e7ab64849a569d3899bfe2ed8c2267 100644 (file)
@@ -111,6 +111,13 @@ function shouldSetAsProp(
     return false
   }
 
+  // #13946 iframe.sandbox should always be set as attribute since setting
+  // the property to null results in 'null' string, and setting to empty string
+  // enables the most restrictive sandbox mode instead of no sandboxing.
+  if (key === 'sandbox' && el.tagName === 'IFRAME') {
+    return false
+  }
+
   // #1787, #2840 form property on form elements is readonly and must be set as
   // attribute.
   if (key === 'form') {