title: Validating base64 encoded images
body: <p>I'm building an application that allows the user to <code>POST</code> HTML5 canvas data that is then encoded in base64 and displayed to all users. I am considering parsing the data into an actual .png file and storing on the server, but the base64 route allows me to store the images in a database and minimize requests. The images are unique, few, and the page won't be refreshed often.</p>
  
  <p>A bit of jQuery will take the canvas data, <code>data:image/png;base64,iVBORw...</code> and passes it along to a PHP script that wraps it like so: <code>&lt;img src="$data"&gt;&lt;/img&gt;</code></p>
  
  <p>However, security is cornerstone and need to validate the base64 canvas data to prevent passing malicious data in the <code>POST</code> request. My primary concern is to prevent external URLs from being injected into the <code>&lt;img&gt;</code> tag and being requested on page load.</p>
  
  <p>I currently have a setup like this:</p>
  
  <pre><code>$data = (isset($_POST['canvas']) &amp;&amp; is_string($_POST['canvas'])) ? $_POST['canvas'] : null;
  $base = str_replace('data:image/png;base64,', '', $data);
  $regx = '~^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$~'
  
  if ((substr($data, 0, 22)) !== 'data:image/png;base64,')
  {
    // Obviously fake, doesn't contain the expected first 22 characters.
    return false;
  }
  
  if ((base64_encode(base64_decode($base64, true))) !== $base64)
  {
    // Decoding and re-encoding the data fails, something is wrong
    return false;
  }
  
  if ((preg_match($regx, $base64)) !== 1) 
  {
    // The data doesn't match the regular expression, discard
    return false;
  }
  
  return true;
  </code></pre>
  
  <p>I want to make sure my current setup is safe enough to prevent external URLs from being inserted into the <code>&lt;img&gt;</code> tag, and if not, what can be done to further validate the image data?</p>