[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Public WebGL] Proposed change to WebGL spec section 4.2 (Security Origin Restrictions)

Currently section 4.2 of the specification provides a sufficient but not necessary restriction on readPixels to prevent reading data from other origins. Greater functionality could be given to application developers by slightly increasing the complexity here, while still maintaining the desired security.

I propose that rather than texImage2D from a different origin or unclean resource causing the canvas to be marked as unclean, it would set a flag marking that texture as unclean, and also set a flag marking the current framebuffer as unclean. Binding a texture would set the flag marking the framebuffer as unclean if the bound texture is marked as unclean. Changing the attached framebuffer would set the flag marking the new framebuffer as unclean if any bound texture is marked as unclean. The origin-clean flag of the canvas would reflect the status of the currently bound framebuffer.

This would allow developers to read the contents of a framebuffer from a context where different origin images were used, but only in certain same circumstances, such as the following pseudocode:

create texture A
bind texture A
texImage2D into A with different origin data // canvas, default framebuffer, and texture are all now unclean
draw some stuff using texture A and cached buffers
bind null in place of texture A // canvas and default framebuffer are still marked as unclean
create framebuffer B // framebuffer B is clean
bind framebuffer B // canvas and framebuffer B are marked as clean
draw some stuff using same cached buffers but not texture A
readPixels // this can now succeed because the unclean data has never been connected to framebuffer B
bind default framebuffer // canvas now back to unclean because default framebuffer is unclean
bind texture A

This is a significant win over using separate canvases for the two operations if the unclean drawing and the clean drawing share a significant amount of buffered data or clean textures.

As an example of how this could be used, say you had a 3d game that showed ads on billboards in the game. The ads are served as images by some other domain. You want to include a way to take screenshots in the game. For a screenshot, you use a different framebuffer and don't bind the images for ads, you render a black box or an ad placeholder image from the clean origin instead. You want to reuse all of the buffered data and clean textures for the screenshot, so using a different canvas would be painful and slow. Using this proposed change you would be able to read the pixels from the alternate framebuffer as long as no ad textures were ever bound at the same time as that framebuffer.


Brian Cornell