Changeset 88387 in webkit
- Timestamp:
- Jun 8, 2011 2:27:51 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r88386 r88387 1 2011-06-08 Kenneth Russell <kbr@google.com> 2 3 Reviewed by Adam Barth. 4 5 Disallow use of cross-domain media (images, video) in WebGL 6 https://bugs.webkit.org/show_bug.cgi?id=62257 7 8 Updated origin-clean-conformance.html to track upstream version in 9 Khronos repository. Added new layout tests mirroring those added 10 in bug 61015 which verify that new CORS support for images is 11 working in the context of WebGL. 12 13 Verified new tests in WebKit and Chromium. 14 15 * http/tests/canvas/webgl/origin-clean-conformance-expected.txt: 16 * http/tests/canvas/webgl/origin-clean-conformance.html: 17 * http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt: Added. 18 * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt: Added. 19 * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html: Added. 20 * http/tests/security/webgl-remote-read-remote-image-allowed.html: Added. 21 * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added. 22 * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html: Added. 23 * platform/mac-wk2/Skipped: 24 1 25 2011-06-08 John Bauman <jbauman@chromium.org> 2 26 -
trunk/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt
r68460 r88387 1 This test ensures WebGL implementations follow proper origin restrictions.1 This test ensures WebGL implementations follow proper same-origin restrictions. 2 2 3 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". … … 6 6 PASS img was loaded 7 7 8 check that copying an img from another origin clears the origin-clean flag. 9 PASS should not throw exception by readPixels for origin clean canvas. 10 PASS should not throw exception by toDataURL for origin clean canvas. 11 PASS should throw exception by readPixels for NON origin clean canvas. 8 check that an attempt to upload an image from another origin throws an exception. 9 PASS texImage2D with cross-origin image should throw exception. 10 PASS texSubImage2D with cross-origin image should throw exception. 11 check that readPixels and toDataURL continue to work against this canvas. 12 PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas. 13 PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean. 14 check that an attempt to upload a tainted canvas throws an exception. 12 15 PASS should throw exception by toDataURL for NON origin clean canvas. 13 14 check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas. 15 PASS should not throw exception by readPixels for origin clean canvas. 16 PASS should not throw exception by toDataURL for origin clean canvas. 17 PASS should throw exception by readPixels for NON origin clean canvas. 18 PASS should throw exception by toDataURL for NON origin clean canvas. 19 20 check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas. 21 PASS should not throw exception by toDataURL for origin clean canvas. 22 PASS should throw exception by toDataURL for NON origin clean canvas. 23 24 check that copying a video from another origin clears the origin-clean flag. 25 PASS should not throw exception by readPixels for origin clean canvas. 26 PASS should not throw exception by toDataURL for origin clean canvas. 27 PASS should throw exception by readPixels for NON origin clean canvas. 28 PASS should throw exception by toDataURL for NON origin clean canvas. 16 PASS texImage2D with NON origin clean canvas should throw exception. 17 PASS texSubImage2D with NON origin clean canvas should throw exception. 18 check that readPixels and toDataURL continue to work against this canvas. 19 PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas. 20 PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean. 21 check that an attempt to upload a video from another origin throws an exception. 22 PASS texImage2D with cross-origin video should throw exception. 23 PASS texSubImage2D with cross-origin video should throw exception. 24 check that readPixels and toDataURL continue to work against this canvas. 25 PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas. 26 PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean. 29 27 30 28 TEST COMPLETE 31 29 -
trunk/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html
r68460 r88387 83 83 } 84 84 85 var testVideo = false; 86 85 87 function init() { 86 88 var video = document.getElementById("video"); … … 109 111 video.addEventListener("playing", runTests); 110 112 video.play(); 113 testVideo = true; 111 114 } else { 112 115 // Still run the other tests, even if the video failed. … … 116 119 117 120 function runTests() { 118 description("This test ensures WebGL implementations follow proper origin restrictions.");121 description("This test ensures WebGL implementations follow proper same-origin restrictions."); 119 122 var img = document.getElementById("img"); 120 123 assertMsg(img.width > 0 && img.height > 0, "img was loaded"); 124 125 function makeTexImage2D(gl, src) { 126 return function() { 127 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); 128 }; 129 } 130 131 function makeTexSubImage2D(gl, src) { 132 return function() { 133 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); 134 }; 135 } 121 136 122 137 function makeReadPixels(gl) { … … 133 148 } 134 149 150 var canvas1 = document.getElementById("canvas1"); 151 var gl = create3DContext(canvas1); 152 135 153 debug(""); 136 debug("check that copying an img from another origin clears the origin-clean flag."); 137 var canvas1 = document.getElementById("canvas1"); 138 var gl1 = create3DContext(canvas1); 139 assertMsg(!causedException(makeReadPixels(gl1)), 140 "should not throw exception by readPixels for origin clean canvas."); 154 debug("check that an attempt to upload an image from another origin throws an exception."); 155 var tex = gl.createTexture(); 156 gl.bindTexture(gl.TEXTURE_2D, tex); 157 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 158 assertMsg(causedException(makeTexImage2D(gl, img)), 159 "texImage2D with cross-origin image should throw exception."); 160 assertMsg(causedException(makeTexSubImage2D(gl, img)), 161 "texSubImage2D with cross-origin image should throw exception."); 162 163 debug("check that readPixels and toDataURL continue to work against this canvas."); 164 assertMsg(!causedException(makeReadPixels(gl)), 165 "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas."); 141 166 assertMsg(!causedException(makeToDataURL(canvas1)), 142 "should not throw exception by toDataURL for origin clean canvas."); 143 144 var tex = gl1.createTexture(); 145 gl1.bindTexture(gl1.TEXTURE_2D, tex); 146 gl1.texImage2D(gl1.TEXTURE_2D, 0, gl1.RGBA, gl1.RGBA, gl1.UNSIGNED_BYTE, img); 147 148 assertMsg(causedException(makeReadPixels(gl1)), 149 "should throw exception by readPixels for NON origin clean canvas."); 150 assertMsg(causedException(makeToDataURL(canvas1)), 151 "should throw exception by toDataURL for NON origin clean canvas."); 152 153 debug(""); 154 debug("check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas."); 167 "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean."); 168 169 debug("check that an attempt to upload a tainted canvas throws an exception."); 155 170 var canvas2 = document.getElementById("canvas2"); 156 var gl2 = create3DContext(canvas2); 157 158 assertMsg(!causedException(makeReadPixels(gl2)), 159 "should not throw exception by readPixels for origin clean canvas."); 160 assertMsg(!causedException(makeToDataURL(canvas2)), 161 "should not throw exception by toDataURL for origin clean canvas."); 162 163 var tex = gl2.createTexture(); 164 gl2.bindTexture(gl2.TEXTURE_2D, tex); 165 gl2.texImage2D( 166 gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1); 167 168 assertMsg(causedException(makeReadPixels(gl2)), 169 "should throw exception by readPixels for NON origin clean canvas."); 171 var ctx2d = canvas2.getContext("2d"); 172 ctx2d.drawImage(img, 0, 0); 170 173 assertMsg(causedException(makeToDataURL(canvas2)), 171 174 "should throw exception by toDataURL for NON origin clean canvas."); 172 173 debug(""); 174 debug("check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas."); 175 var canvas3 = document.getElementById("canvas3"); 176 var ctx2d = canvas3.getContext("2d"); 177 assertMsg(!causedException(makeToDataURL(canvas3)), 178 "should not throw exception by toDataURL for origin clean canvas."); 179 ctx2d.drawImage(canvas2, 0, 0); 180 assertMsg(causedException(makeToDataURL(canvas3)), 181 "should throw exception by toDataURL for NON origin clean canvas."); 182 183 debug(""); 184 debug("check that copying a video from another origin clears the origin-clean flag."); 185 var canvas4 = document.getElementById("canvas4"); 186 var gl4 = create3DContext(canvas4); 187 assertMsg(!causedException(makeReadPixels(gl4)), 188 "should not throw exception by readPixels for origin clean canvas."); 189 assertMsg(!causedException(makeToDataURL(canvas4)), 190 "should not throw exception by toDataURL for origin clean canvas."); 191 var tex4 = gl4.createTexture(); 192 gl4.bindTexture(gl4.TEXTURE_2D, tex4); 193 gl4.texImage2D( 194 gl4.TEXTURE_2D, 0, gl4.RGBA, gl4.RGBA, gl4.UNSIGNED_BYTE, video); 195 assertMsg(causedException(makeReadPixels(gl4)), 196 "should throw exception by readPixels for NON origin clean canvas."); 197 assertMsg(causedException(makeToDataURL(canvas4)), 198 "should throw exception by toDataURL for NON origin clean canvas."); 175 assertMsg(causedException(makeTexImage2D(gl, canvas2)), 176 "texImage2D with NON origin clean canvas should throw exception."); 177 assertMsg(causedException(makeTexSubImage2D(gl, canvas2)), 178 "texSubImage2D with NON origin clean canvas should throw exception."); 179 180 debug("check that readPixels and toDataURL continue to work against this canvas."); 181 assertMsg(!causedException(makeReadPixels(gl)), 182 "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas."); 183 assertMsg(!causedException(makeToDataURL(canvas1)), 184 "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean."); 185 186 if (testVideo) { 187 debug("check that an attempt to upload a video from another origin throws an exception."); 188 var video = document.getElementById("video"); 189 assertMsg(causedException(makeTexImage2D(gl, video)), 190 "texImage2D with cross-origin video should throw exception."); 191 assertMsg(causedException(makeTexSubImage2D(gl, video)), 192 "texSubImage2D with cross-origin video should throw exception."); 193 194 debug("check that readPixels and toDataURL continue to work against this canvas."); 195 assertMsg(!causedException(makeReadPixels(gl)), 196 "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas."); 197 assertMsg(!causedException(makeToDataURL(canvas1)), 198 "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean."); 199 } 199 200 200 201 debug('<br /><span class="pass">TEST COMPLETE</span>'); … … 212 213 <canvas id="canvas1"></canvas> 213 214 <canvas id="canvas2"></canvas> 214 <canvas id="canvas3"></canvas>215 <canvas id="canvas4"></canvas>216 215 <img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;"> 217 216 <video id="video" style="display:none;"/> -
trunk/LayoutTests/platform/mac-wk2/Skipped
r88236 r88387 985 985 http/tests/navigation/ping-cross-origin.html 986 986 http/tests/navigation/ping-same-origin.html 987 http/tests/security/webgl-remote-read-remote-image-allowed.html 988 http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html 989 http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html 987 990 loader/go-back-to-different-window-size.html 988 991 media/restore-from-page-cache.html -
trunk/Source/WebCore/ChangeLog
r88386 r88387 1 2011-06-08 Kenneth Russell <kbr@google.com> 2 3 Reviewed by Adam Barth. 4 5 Disallow use of cross-domain media (images, video) in WebGL 6 https://bugs.webkit.org/show_bug.cgi?id=62257 7 8 Updated WebGL implementation to track recent spec updates in this area. 9 10 Tests: http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html 11 http/tests/security/webgl-remote-read-remote-image-allowed.html 12 http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html 13 14 * html/canvas/CanvasRenderingContext.cpp: 15 (WebCore::CanvasRenderingContext::wouldTaintOrigin): 16 (WebCore::CanvasRenderingContext::checkOrigin): 17 * html/canvas/CanvasRenderingContext.h: 18 (WebCore::CanvasRenderingContext::checkOrigin): 19 * html/canvas/WebGLRenderingContext.cpp: 20 (WebCore::WebGLRenderingContext::readPixels): 21 (WebCore::WebGLRenderingContext::texImage2D): 22 (WebCore::WebGLRenderingContext::videoFrameToImage): 23 (WebCore::WebGLRenderingContext::texSubImage2D): 24 * html/canvas/WebGLRenderingContext.h: 25 1 26 2011-06-08 John Bauman <jbauman@chromium.org> 2 27 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
r87539 r88387 42 42 } 43 43 44 void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)44 bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern) 45 45 { 46 46 if (canvas()->originClean() && pattern && !pattern->originClean()) 47 canvas()->setOriginTainted(); 47 return true; 48 return false; 48 49 } 49 50 50 void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)51 bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas) 51 52 { 52 53 if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean()) 53 canvas()->setOriginTainted(); 54 return true; 55 return false; 54 56 } 55 57 56 void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)58 bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image) 57 59 { 58 60 if (!image || !canvas()->originClean()) 59 return ;61 return false; 60 62 61 63 CachedImage* cachedImage = image->cachedImage(); 62 if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) 63 checkOrigin(cachedImage->response().url()); 64 if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) { 65 if (wouldTaintOrigin(cachedImage->response().url())) 66 return true; 67 } 64 68 65 if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin()) 66 canvas()->setOriginTainted(); 69 if (!cachedImage->image()->hasSingleSecurityOrigin()) 70 return true; 71 72 return false; 67 73 } 68 74 69 void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)75 bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video) 70 76 { 71 77 #if ENABLE(VIDEO) … … 74 80 // make currentSrc be the final URL because then the 75 81 // HTMLMediaElement.currentSrc DOM API would leak redirect destinations! 76 checkOrigin(video->currentSrc()); 77 if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin()) 78 canvas()->setOriginTainted(); 82 if (!video || !canvas()->originClean()) 83 return false; 84 85 if (wouldTaintOrigin(video->currentSrc())) 86 return true; 87 88 if (!video->hasSingleSecurityOrigin()) 89 return true; 79 90 #endif 91 92 return false; 93 } 94 95 bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url) 96 { 97 if (!canvas()->originClean() || m_cleanURLs.contains(url.string())) 98 return false; 99 100 if (canvas()->securityOrigin()->taintsCanvas(url)) 101 return true; 102 103 m_cleanURLs.add(url.string()); 104 return false; 80 105 } 81 106 82 107 void CanvasRenderingContext::checkOrigin(const KURL& url) 83 108 { 84 if (!canvas()->originClean() || m_cleanOrigins.contains(url.string())) 85 return; 86 87 if (canvas()->securityOrigin()->taintsCanvas(url)) 109 if (wouldTaintOrigin(url)) 88 110 canvas()->setOriginTainted(); 89 else90 m_cleanOrigins.add(url.string());91 111 } 92 112 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h
r84764 r88387 64 64 protected: 65 65 CanvasRenderingContext(HTMLCanvasElement*); 66 void checkOrigin(const CanvasPattern*); 67 void checkOrigin(const HTMLCanvasElement*); 68 void checkOrigin(const HTMLImageElement*); 69 void checkOrigin(const HTMLVideoElement*); 66 bool wouldTaintOrigin(const CanvasPattern*); 67 bool wouldTaintOrigin(const HTMLCanvasElement*); 68 bool wouldTaintOrigin(const HTMLImageElement*); 69 bool wouldTaintOrigin(const HTMLVideoElement*); 70 bool wouldTaintOrigin(const KURL&); 71 72 template<class T> void checkOrigin(const T* arg) 73 { 74 if (wouldTaintOrigin(arg)) 75 canvas()->setOriginTainted(); 76 } 70 77 void checkOrigin(const KURL&); 71 78 72 79 private: 73 80 HTMLCanvasElement* m_canvas; 74 HashSet<String> m_clean Origins;81 HashSet<String> m_cleanURLs; 75 82 }; 76 83 -
trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
r87451 r88387 2808 2808 } 2809 2809 2810 void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) 2811 { 2812 if (isContextLost()) 2813 return; 2814 if (!canvas()->originClean()) { 2815 ec = SECURITY_ERR; 2816 return; 2817 } 2810 void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&) 2811 { 2812 if (isContextLost()) 2813 return; 2814 // Due to WebGL's same-origin restrictions, it is not possible to 2815 // taint the origin using the WebGL API. 2816 ASSERT(canvas()->originClean()); 2818 2817 // Validate input parameters. 2819 2818 if (!pixels) { … … 3158 3157 if (!validateHTMLImageElement(image)) 3159 3158 return; 3160 checkOrigin(image); 3159 if (wouldTaintOrigin(image)) { 3160 ec = SECURITY_ERR; 3161 return; 3162 } 3163 3161 3164 texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(), 3162 3165 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); … … 3173 3176 return; 3174 3177 } 3175 checkOrigin(canvas); 3178 if (wouldTaintOrigin(canvas)) { 3179 ec = SECURITY_ERR; 3180 return; 3181 } 3176 3182 RefPtr<ImageData> imageData = canvas->getImageData(); 3177 3183 if (imageData) … … 3183 3189 3184 3190 #if ENABLE(VIDEO) 3185 PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video )3191 PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec) 3186 3192 { 3187 3193 if (!video || !video->videoWidth() || !video->videoHeight()) { … … 3195 3201 return 0; 3196 3202 } 3197 checkOrigin(video); 3203 if (wouldTaintOrigin(video)) { 3204 ec = SECURITY_ERR; 3205 return 0; 3206 } 3198 3207 IntRect destRect(0, 0, size.width(), size.height()); 3199 3208 // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback. … … 3208 3217 if (isContextLost()) 3209 3218 return; 3210 RefPtr<Image> image = videoFrameToImage(video );3211 if (! video)3219 RefPtr<Image> image = videoFrameToImage(video, ec); 3220 if (!image) 3212 3221 return; 3213 3222 texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); … … 3350 3359 if (!validateHTMLImageElement(image)) 3351 3360 return; 3352 checkOrigin(image); 3361 if (wouldTaintOrigin(image)) { 3362 ec = SECURITY_ERR; 3363 return; 3364 } 3353 3365 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(), 3354 3366 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); … … 3365 3377 return; 3366 3378 } 3367 checkOrigin(canvas); 3379 if (wouldTaintOrigin(canvas)) { 3380 ec = SECURITY_ERR; 3381 return; 3382 } 3368 3383 RefPtr<ImageData> imageData = canvas->getImageData(); 3369 3384 if (imageData) … … 3381 3396 if (isContextLost()) 3382 3397 return; 3383 RefPtr<Image> image = videoFrameToImage(video );3384 if (! video)3398 RefPtr<Image> image = videoFrameToImage(video, ec); 3399 if (!image) 3385 3400 return; 3386 3401 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); -
trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h
r84764 r88387 345 345 346 346 #if ENABLE(VIDEO) 347 PassRefPtr<Image> videoFrameToImage(HTMLVideoElement* );347 PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&); 348 348 #endif 349 349
Note: See TracChangeset
for help on using the changeset viewer.