浏览代码

fix(runtime-dom): ensure iframe sandbox is handled as an attribute to prevent unintended behavior (#13950)

close #13946
clay jenson 5 月之前
父节点
当前提交
5689884c8e
共有 2 个文件被更改,包括 41 次插入0 次删除
  1. 34 0
      packages/runtime-dom/__tests__/patchAttrs.spec.ts
  2. 7 0
      packages/runtime-dom/src/patchProp.ts

+ 34 - 0
packages/runtime-dom/__tests__/patchAttrs.spec.ts

@@ -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
+  })
 })

+ 7 - 0
packages/runtime-dom/src/patchProp.ts

@@ -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') {