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

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>20034</bug_id>
          
          <creation_ts>2012-11-21 05:52:50 +0000</creation_ts>
          <short_desc>canvas getImageData opens security whole for code</short_desc>
          <delta_ts>2012-11-22 05:22:36 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>HTML WG</product>
          <component>HTML Canvas 2D Context</component>
          <version>unspecified</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>WONTFIX</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>critical</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Klaus Bertram">bertram</reporter>
          <assigned_to name="rcabanie">cabanier</assigned_to>
          <cc>bertram</cc>
    
    <cc>bzbarsky</cc>
    
    <cc>cabanier</cc>
    
    <cc>mike</cc>
    
    <cc>public-html-admin</cc>
    
    <cc>public-html-wg-issue-tracking</cc>
          
          <qa_contact name="HTML WG Bugzilla archive list">public-html-bugzilla</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>78564</commentid>
    <comment_count>0</comment_count>
      <attachid>1249</attachid>
    <who name="Klaus Bertram">bertram</who>
    <bug_when>2012-11-21 05:52:50 +0000</bug_when>
    <thetext>Created attachment 1249
sample image and html side

With the canvas it is possible to read byte data out of an image.
Images himself can come from different urls (hosts) without restriction.
What happens when someone fill an image with code values as pixel data, load the image into an canvas and interpret it?
He could execute code without any knowledge of any security prevention because the &quot;code&quot; are an image.
What I&apos;ve done is simple:
1. create an image where the pixel are the color representation of
  window[&apos;alert&apos;](&apos;xss&apos;)
  this could be an gif, png... It depends of the color interpolation in the resulting image.
2. load the image into a web side
3. create an canvas object an put the image inside.
4. read the byte data of the canvas and cast it as string to eval
Eh viola

This is small js for it:
var img=new Image();
img.onload=function()
{
var ca = document.createElement(&apos;canvas&apos;);
ca.width=this.width;
ca.height=this.height;
var ctx = ca.getContext(&apos;2d&apos;);
ctx.drawImage(this,0,0);
var a=&quot;&quot;,d=ctx.getImageData(0, 0,this.width, this.height).data;
for(var i=0;i&lt;d.length;i++){
if(d[i]&lt;255) a+=String.fromCharCode(d[i]);
}
eval(a);
}
img.src=&quot;exploid.gif&quot;;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78565</commentid>
    <comment_count>1</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2012-11-21 06:02:19 +0000</bug_when>
    <thetext>I&apos;m going to regret this...

How is this different from doing an XMLHttpRequest to get the data as a string and calling eval()?

Seems like the real problem here is calling eval() on a string of unknown provenance, no?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78566</commentid>
    <comment_count>2</comment_count>
    <who name="Klaus Bertram">bertram</who>
    <bug_when>2012-11-21 06:10:17 +0000</bug_when>
    <thetext>It is very different, becouse here normal firewalls and intrusion detection systems has a chance to interpret and revert the text (code), but as an image not</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78567</commentid>
    <comment_count>3</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2012-11-21 06:38:45 +0000</bug_when>
    <thetext>&gt; becouse here normal firewalls and intrusion detection systems has a chance to
&gt; interpret and revert the text (code)

How, exactly?  All they know is the browser is doing an HTTP GET.  The server returns an image.  What exactly is the firewall detecting?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78568</commentid>
    <comment_count>4</comment_count>
    <who name="Klaus Bertram">bertram</who>
    <bug_when>2012-11-21 07:12:21 +0000</bug_when>
    <thetext>If you have some intrusion detection systems, virus scanner and so on they try to find in every request signatures of possible code. That&apos;s one of the points why exploit kits obfuscate and encrypt their code. With this it is not needed any more and the images can come from any legal image library.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78574</commentid>
    <comment_count>5</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2012-11-21 15:44:13 +0000</bug_when>
    <thetext>Ah, so your concern is that the code signature will not be found because the image encoder obfuscates it?

How is that different from any other obfuscation method applied to code that&apos;s fetched with XHR?

What&apos;s the attack model here?  Is the code calling eval() actively trying to smuggle in code somewhere, such that it&apos;s cooperating with the server the image is coming from to do so?  Or is the server an attacker while the code calling eval() is not trying to do anything bad?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78576</commentid>
    <comment_count>6</comment_count>
    <who name="Klaus Bertram">bertram</who>
    <bug_when>2012-11-21 16:20:28 +0000</bug_when>
    <thetext>Yes that&apos;s my concern because:
Every Browser can load images from elsewhere without restrictions. There is no validation of it. 
When you has normal XHR code there is per default an validation of the same host.
Also any Virus detection tools can block it when they found a signature of malicious text (code).
This is not given in an image.

Before canvas, there was for my opinion no chance to get the byte data on any image values. So you can&apos;t deliver code in it.

The attack model here is with 3 lines of legal code and via image loading an attack is possible from single user to enterprise company’s.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78609</commentid>
    <comment_count>7</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2012-11-21 21:04:52 +0000</bug_when>
    <thetext>&gt; When you has normal XHR code there is per default an validation of the same
&gt; host.

Yes, but hosts can opt in to loads from them.

And while browsers can load images from anywhere, and draw them into a canvas, they can only getImageData the result if the image was from the same host or if the host opted into it, just like XHR.

&gt; Also any Virus detection tools can block it when they found a signature of
&gt; malicious text (code).

Again, if the web page is not cooperating, right?  If the web page and the server are cooperating, then they can just obfuscate the source code (rot13, encrypt, encode as an image, whatever).

It really would help if you answered my questions about your attack model... because as far as I can tell, getImageData doesn&apos;t allow anything XMLHttpRequest didn&apos;t already allow.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78626</commentid>
    <comment_count>8</comment_count>
    <who name="rcabanie">cabanier</who>
    <bug_when>2012-11-22 04:35:02 +0000</bug_when>
    <thetext>(In reply to comment #7)
&gt; &gt; When you has normal XHR code there is per default an validation of the same
&gt; &gt; host.
&gt; 
&gt; Yes, but hosts can opt in to loads from them.
&gt; 
&gt; And while browsers can load images from anywhere, and draw them into a
&gt; canvas, they can only getImageData the result if the image was from the same
&gt; host or if the host opted into it, just like XHR.
&gt; 
&gt; &gt; Also any Virus detection tools can block it when they found a signature of
&gt; &gt; malicious text (code).
&gt; 
&gt; Again, if the web page is not cooperating, right?  If the web page and the
&gt; server are cooperating, then they can just obfuscate the source code (rot13,
&gt; encrypt, encode as an image, whatever).
&gt; 
&gt; It really would help if you answered my questions about your attack model...
&gt; because as far as I can tell, getImageData doesn&apos;t allow anything
&gt; XMLHttpRequest didn&apos;t already allow.

I agree.
A script has multiple other ways to obfuscate malicious code.
This is an interesting way of new way of transmitting JS code, but it doesn&apos;t open up a new attack vector since it&apos;s easy to encrypt JS.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78628</commentid>
    <comment_count>9</comment_count>
    <who name="rcabanie">cabanier</who>
    <bug_when>2012-11-22 04:35:38 +0000</bug_when>
    <thetext>EDITOR&apos;S RESPONSE: 
This is an Editor&apos;s Response to your comment. If
you are satisfied with this response, please change the state of
this bug to CLOSED. If you have additional information and would
like the Editor to reconsider, please reopen this bug. If you would
like to escalate the issue to the full HTML Working Group, please
add the TrackerRequest keyword to this bug, and suggest title and
text for the Tracker Issue; or you may create a Tracker Issue
yourself, if you are able to do so. For more details, see this
document:
       http://dev.w3.org/html5/decision-policy/decision-policy.html</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>1249</attachid>
            <date>2012-11-21 05:52:50 +0000</date>
            <delta_ts>2012-11-21 05:52:50 +0000</delta_ts>
            <desc>sample image and html side</desc>
            <filename>canvas.zip</filename>
            <type>application/zip</type>
            <size>716</size>
            <attacher name="Klaus Bertram">bertram</attacher>
            
              <data encoding="base64">UEsDBBQDAAAIAFiUdEEyiVa5OAAAADkAAAALAAAAZXhwbG9pZC5naWZz93SzME/kYGBkOMTBoKFe
Ea2eWKIem5NaVJ6Zl5JfXlysrvn/vw4DEIDUMDCzeYgqJ6gzMlgDAFBLAwQUAwAACAAcLnVBKzqm
ALwBAADTAgAACgAAAGluZGV4Lmh0bWxlUk2L3DAMvedXqLlswmQ8swt7mnhgmQ50z22hUHrQxEpi
SOzU0Xyx9L9XTtJ2oSfL8ntPepLLD8ZXfB8IWu67fVL+OQiNHD0xygsPa/p5thedflt/fVkffD8g
21NHKVTeMTnW6etRH01D6UZoYxXswPvkggFs32hHV3jtsaEs3yWSUN51Ho2uz65i612WJ28TuELQ
IB2de9FUVSBkOnYUb9lDhe6C44NIVKiu1nCrubXjHE7JlmzT8pRd4t0syzfRFUBDfIgN30TuyUQp
eVIm4HVuLzKLbbHNZx7qNC2MFkxkTpCPyJhtC9gW/2oX8K5iroxAdkntQzb519udLY3qyDXSpl2t
8rfE1pn5bn+UT8/POeBKf+ZgXaPq4PtDi+HgDU0A6eNXQhfsMozhNLsxVDql29B5a1Rj63SXlJtl
4hItmzt5c497fNwfprGBjd3DwhPYo7wO+5eaKUBchtQXG7Tg7v4MIxGgA+woMJz8Da6WW0hv45iC
daM1pL6Ib8BAchedIRCTgejinVQcB7S2H6mrVbkZprrwicJcRbYaKwkBeWE1EFUdOB967BaZMub/
877Zq79eN/Pf/Q1QSwECPwMUAwAACABYlHRBMolWuTgAAAA5AAAACwAAAAAAAAAAACCApIEAAAAA
ZXhwbG9pZC5naWZQSwECPwMUAwAACAAcLnVBKzqmALwBAADTAgAACgAAAAAAAAAAACCApIFhAAAA
aW5kZXguaHRtbFBLBQYAAAAAAgACAHEAAABFAgAAAAA=
</data>

          </attachment>
      

    </bug>

</bugzilla>