title: Properly-preventing XSS in cross-origin iframe messages
body: <p>I'm building a site where anyone will be able to interact with my iFrame through the postMessage command (i.e. sandboxed functions, not total control of the window). How can I do that without exposing my visitor's cookies through XSS? <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Security_concerns" rel="noreferrer">https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Security_concerns</a></p>
  
  <p>Let's say I have the following receive function:</p>
  
  <pre><code>var secret = localStorage.getItem("secret");
  
  window.addEventListener(message,function(e){
       // any e.origin is allowed
       if(e.func=="doX"){
              var string = e.data.string1 * e.data.string2;
  
       }else if(e.func=="doY"){
              // another javascript function, no DOM interaction
              config[e.data.key] = e.data.value;
  
       }else if(e.func=="doZ"){
            document.getElementById("app")=e.data.title
            document.getElementById("description")=e.data.description
       }
  })
  
  
  </code></pre>
  
  <p>I read on the Mozilla page that allowing request from any origin is pretty dangerous. How can I properly prevent XSS for each of the doX, doY, and doZ scenarious? </p>
  
  <p>I gave it a try too. Are these functions safe?</p>
  
  <pre><code>var secret = localStorage.getItem("secret");
  
  window.addEventListener(message,function(e){
       // any e.origin is allowed
       if(typeof e.func!=Number) return;
  
       if( e.func &lt; 0 || e.func &gt; 2) return;
  
       if(e.func==0){ //  we will call this "Safe 0"
  
              if(e.data.num1 &gt; 1000 || e.data.num2 &gt; 1000) return;
              var num3 = e.data.num1 * e.data.num2;
  
       }else if(e.func==1){ // safe 1
  
              if(!isHex(e.data.value))return; // see below for isHex func
  
              config['something'] = e.data.value;
  
       }else if(e.func==2){ // safe 2
  
            if(e.data.title.length &lt; 8) document.getElementById("app")=e.data.title;
  
            if(e.data.description.length &lt; 15)document.getElementById("description")=e.data.description
  
       }
  })
  function isHex(h) {
  
      var a = parseInt(h,16);
      return (a.toString(16) === h)
  
  }
  
  </code></pre>
  
  <p>I have learned that HTML input elements will also be inaccessible from the hosting site, meaning that these "postMessage"s are the main source of vulnerability. Source for this last statement: <a href="https://stackoverflow.com/questions/15002652/get-value-of-input-field-inside-an-iframe">Get value of input field inside an iframe</a></p>