<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>182097</bug_id>
          
          <creation_ts>2018-01-25 05:45:34 -0800</creation_ts>
          <short_desc>Built-in types read from IndexedDB have corrupt prototype chain and fail instanceof checks</short_desc>
          <delta_ts>2018-11-29 10:53:20 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>Safari Technology Preview</version>
          <rep_platform>Mac</rep_platform>
          <op_sys>macOS 10.12</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>DUPLICATE</resolution>
          <dup_id>185906</dup_id>
          
          <bug_file_loc>https://fiddle.jshell.net/sechel/zg0dnx3t/</bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Stefan Sechelmann">stefan</reporter>
          <assigned_to name="WebKit Security Group">webkit-security-unassigned</assigned_to>
          <cc>bfulgham</cc>
    
    <cc>product-security</cc>
    
    <cc>sihui_liu</cc>
    
    <cc>stefan</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>webkit</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1393005</commentid>
    <comment_count>0</comment_count>
    <who name="Stefan Sechelmann">stefan</who>
    <bug_when>2018-01-25 05:45:34 -0800</bug_when>
    <thetext>In a same-origin iframe, the prototype chain of built-in types such as Object,
Array, CryptoKey, and so on is corrupt when an object is returned from IndexedDB.
Note that, if run in top level context all types are correct. The reason why we 
think this is security related is that WebCrypto keys are also affected. For a key 
read from IDB `key instanceof CryptoKey` will yield false. At the same time it is
perfectly usable with the `crypto.subtle` API.

See https://fiddle.jshell.net/sechel/zg0dnx3t/ for a demonstration:

QUnit.test(&apos;safari indexeddb issue, Native&apos;, async assert =&gt; {
  // check types before insert
  assert.ok(data instanceof Object);
  assert.ok(data.key instanceof CryptoKey);
  assert.ok(data.array instanceof Array);
  assert.ok(data.map instanceof Map);
  assert.ok(data.set instanceof Set); 

  // put and get from db
  let req = indexedDB.open(dbName, 1);
  req.onupgradeneeded = function() {
    const db = this.result;
    const store = db.createObjectStore(
      &apos;test&apos;, { autoIncrement: true, keyPath: &apos;id&apos; }
    );
    store.createIndex(&apos;id&apos;, &apos;id&apos;, { unique: true });
  };  
  await new Promise(r =&gt; req.onsuccess = r);
  const db = req.result;
  let tx = db.transaction([&apos;test&apos;], &apos;readwrite&apos;);
  let store = tx.objectStore(&apos;test&apos;);
  store.add(data);
  await new Promise(r =&gt; tx.oncomplete = r);
  tx = db.transaction([&apos;test&apos;], &apos;readonly&apos;);
  store = tx.objectStore(&apos;test&apos;);
  req = store.get(1);
  await new Promise(r =&gt; req.onsuccess = r);
  const result = req.result;
  
  // check types of result
  assert.ok(result instanceof Object);
  assert.ok(result.key instanceof CryptoKey);
  assert.ok(result.array instanceof Array);
  assert.ok(result.map instanceof Map);
  assert.ok(result.set instanceof Set);
  
  // workaround, fix prototypes:
  result.__proto__ = Object.prototype;
  result.key.__proto__ = CryptoKey.prototype;
  result.array.__proto__ = Array.prototype;
  result.map.__proto__ = Map.prototype;
  result.set.__proto__ = Set.prototype;
  assert.ok(result instanceof Object);
  assert.ok(result.key instanceof CryptoKey);
  assert.ok(result.array instanceof Array);
  assert.ok(result.map instanceof Map);
  assert.ok(result.set instanceof Set); 
});
```</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1393007</commentid>
    <comment_count>1</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2018-01-25 05:45:49 -0800</bug_when>
    <thetext>&lt;rdar://problem/36864862&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1483037</commentid>
    <comment_count>2</comment_count>
    <who name="Sihui Liu">sihui_liu</who>
    <bug_when>2018-11-29 10:53:20 -0800</bug_when>
    <thetext>

*** This bug has been marked as a duplicate of bug 185906 ***</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>