Main Page/cms/security

From WebGL Public Wiki
Revision as of 01:41, 3 June 2011 by Kbr google (talk | contribs) (Created page with "The [http://www.khronos.org/webgl/ WebGL API] provides a low-level, shader based, 3D graphics API based on [http://www.khronos.org/opengles OpenGL ES 2.0] that renders directly i...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The WebGL API provides a low-level, shader based, 3D graphics API based on OpenGL ES 2.0 that renders directly into an HTML5 Canvas element. As an API for the World Wide Web, WebGL necessarily conforms to the security principles of the web platform, and was designed with security in mind from day one. This white paper provides an overview of some of the security aspects of the WebGL specification and its implementations.

Undefined Behavior

In the OpenGL ES 2.0 specification, behavior is left undefined in various circumstances, generally in order to achieve the highest performance for native applications on the system. On the web platform, undefined behavior makes it impossible to write strong conformance tests, and may introduce security vulnerabilities. For these reasons the majority of the undefined behavior in OpenGL ES has been specified in the WebGL specification. In general, behavior is only left undefined in the WebGL specification if defining it could significantly impact performance, and there is also a possibility that new techniques or hardware support might avoid such a performance impact in the future.

As one concrete example, consider the readPixels API. In OpenGL ES, if the rectangular region for a particular ReadPixels call extends outside the context's frame buffer, the values for the pixels outside the frame buffer are undefined (see the OpenGL ES 2.0 specification, version 2.0.25, section 4.4.5, p. 105). This behavior is clearly not acceptable for a web API, since it is conceivable that video memory belonging to another application might be returned for these pixels. The WebGL API defines that pixels outside the frame buffer will contain the value (0, 0, 0, 0), and the conformance suite verifies this behavior. WebGL implementations enforce this behavior while attempting to minimize its performance impact; for example, if a given readPixels call is completely within the bounds of the frame buffer, no extra work is necessary.

Out of Range Memory Accesses

Historically, in order to achieve the highest performance for trusted applications on the system, 3D graphics APIs such as OpenGL, OpenGL ES or Direct3D did not perform range checking for most operations. As one example, all of these APIs provide a facility to draw indexed geometry; the application can supply both a set of vertices and a separate set of indices to describe a 3D model. Until fairly recently, none of these APIs verified that each index referred to a valid vertex. In an API like WebGL where untrusted code makes 3D graphics calls, it is essential to ensure that all of the indices are valid, to avoid potential out of range memory accesses. For this reason, the WebGL specification tightly defines the behavior in this particular area. Out of range memory writes are an even more serious potential problem; buffer overruns are a common source of security vulnerabilities on CPUs.

Relatively new APIs like Direct3D 10, and OpenGL extensions such as GL_ARB_robustness, provide stronger guarantees about out of range memory accesses. However, the safeguards defined by these APIs do not necessarily have consistent behavior, so it is not possible to write rigorous conformance tests. In some areas, such as index validation, the WebGL specification therefore defines the behavior in such a way that the WebGL implementation, and not the graphics hardware, must guard against out of range memory accesses. In other areas, the WebGL implementation is solely responsible for the safeguards, and the specification does not define the behavior. The reason for the distinction is to allow innovation in the safeguarding techniques for performance critical areas, which may yield performance improvements over time. As the security aspects of graphics processors continue to improve, responsibility for guarding against out of range memory accesses will likely shift from WebGL implementations to the graphics hardware.

Access to Uninitialized Memory

Again to achieve the highest performance, 3D graphics APIs do not typically clear the contents of newly allocated GPU resources such as textures and vertex buffers. A typical game, upon allocating such a resource, will immediately fill it with data, so zeroing the newly allocated region would impact performance. In the WebGL API, allowing an application to observe potentially uninitialized GPU memory carries high risk; for example, it might be possible to see stale contents of other windows on the system. For this reason, all GPU resources allocated by a WebGL application are initially cleared to zero. While this mandatory clearing may impact performance, WebGL implementations may try to optimize real world scenarios, for example if the entire contents of a texture are specified during its allocation.

Shader Validation and Transformation

WebGL adopts the OpenGL ES Shading Language (ESSL) to describe its vertex and fragment shaders, and reserves some additional identifiers for use by implementations. Restrictions above and beyond those in core ESSL are imposed on WebGL shaders, such as limitations on the structure of loops and indexing expressions in fragment shaders. These restrictions are to achieve maximum portability of WebGL content, not for security reasons. However, a WebGL implementation typically always validates that incoming shaders conform to the ESSL standard before passing the shader to the underlying 3D graphics API, even if running on top of OpenGL ES, so that uniform behavior is achieved on all platforms.

Some transformations to incoming shaders are performed; for example, WebGL supports variable names of a certain length, but there is no guarantee that the shader compiler in the underlying 3D graphics API will do so. Therefore, many WebGL implementations will rename variables in shaders so that they do not exceed a certain length. A transformation such as this is done for security reasons, to avoid buffer overruns in the system's shader compiler.

Denial of Service

If a particular draw call takes a long time to execute, because it contains very many triangles, because the associated shaders are computationally expensive, or for any other reason, the user's system may become unresponsive. This is a longstanding problem in the 3D graphics domain, and is one which has received renewed attention since WebGL has been released, because WebGL allows unknown and untrusted code to access the graphics processor.

Solutions already exist to this problem on some operating systems. For example, Microsoft Windows Vista and later support a new driver model which will reset the graphics processor if it spends too long on any particular operation. The WebGL implementation can detect that the graphics card was reset, warn the user that WebGL content might have caused it, and prompt the user if they want to continue running the content.

The Khronos group has introduced the GL_ARB_robustness OpenGL extension as a platform-independent way to prevent denial of service attacks. A WebGL implementation can use this extension to receive notifications that the graphics card was reset and respond in the manner described above. As of this writing, some GPU vendors support GL_ARB_robustness, while others are in the process of supporting it, and browser vendors are incorporating it into their WebGL implementations. In order to support robust and widespread deployment of WebGL, it is anticipated that browsers may soon require the presence of the GL_ARB_robustness extension in order to enable WebGL content. Follow-on extensions to GL_ARB_robustness are under development which will provide stronger guarantees about the potential side effects one application may have on another when the GPU is reset.

Cross-Origin Media

The web platform imposes restrictions on the use of media, such as an image or video, which comes from different web sites than the hosting web page. For security reasons, JavaScript code on a web page is not allowed to read the pixels of an image or video which comes from a different site. Web APIs like CanvasRenderingContext2D enforce these restrictions in various ways; for example, if a cross-origin image is painted into a canvas, then that canvas's content can no longer be accessed pixel-by-pixel.

The first version of the WebGL specification imposed similar restrictions on the use of cross-domain images and videos as WebGL textures. During the development of the specification, it was noted that because arbitrary shader code can be uploaded to WebGL, it might be possible to cause the shader to run much longer if a given pixel's value was more or less than a certain brightness level, and thereby infer the contents of the image. Recently as of this writing, a proof of concept of this idea was implemented, demonstrating that the ability to reference arbitrary cross-domain media from WebGL introduced a security vulnerability.

In response, Khronos and the WebGL working group have worked with the HTML5 working group to add support for Cross-Origin Resource Sharing, or CORS, to image and video elements. CORS is a specification that allows a web server, upon request from a client such as a web browser, to indicate that a given resource may be used in certain ways. If a server grants universal access to an image, then even if that server is different than that hosting the web page, JavaScript code on the page may access the pixel data of the image.

WebGL will rely on this capability of web servers to continue to support cross-origin images in WebGL programs. Only if the server explicitly grants permission to access the image's contents will it be possible to upload a cross-origin image to a WebGL context. Photo sharing web sites would likely grant these permissions, but, for example, a bank would not when serving scanned images of checks. As of this writing, updates to the WebGL specification and implementations were in progress enforcing these new rules. The Khronos group and WebGL working group are looking forward to working with media hosting services to ensure widespread support for CORS so that advanced WebGL applications can use appropriate cross-origin resources.

Blacklisting graphics drivers

In order to provide the best user experience, browsers may selectively enable or disable support for WebGL, or certain sub-features, in certain situations. This special treatment is typically used to work around stability or conformance problems. WebGL implementations use blacklists and whitelists to encode the rules determining whether WebGL is allowed to run. WebGL-enabled browsers are typically able to update their blacklists quickly without requiring a software update, providing an opportunity for GPU and system vendors to deploy updated drivers without compromising the security of user systems.

Conclusion

WebGL brings the power of GPU accelerated 3D graphics to the web platform with the utmost consideration for security concerns. The Khronos group and WebGL working group are looking forward to widespread deployment of WebGL in a robust and secure manner.