Re: Update on CSS shaders security issue

Hi Benoit,

Thanks a lot for running these experiments and sharing the results.

So I think the summary of the situation with arithmetic operations is:

a. they can be seen/demonstrated on x87 architecture.
b. they cannot be seen (in our current experiments) on GPUs. We would need to test on more GPUs to fully validate this, but it does look this way.
c. they cannot be seen when using SSE scalar/SIMD (your experiments).

To move forward, I propose that for now, we recommend that implementations do not give access to the rendered texture until we complete our research on b. I think that a baseline shader support even without texture access would provide very high value and we can move our way up from that baseline if we can clear the security concerns.

One thing that has been mentioned that I agree with: we need to make sure that the restrictions on fragment shaders in particular will not prevent relaxing constraints in the future. For example, if we do provide a way to specify a 'compositing fragment shader' (one whose output gets automatically combined with the rendered texture), we should still design the features so that a regular shader with rendered content texture access might be used in the future.

Cheers,
-v

From: Benoit Jacob <jacob.benoit.1@gmail.com<mailto:jacob.benoit.1@gmail.com>>
Date: Sat, 21 Apr 2012 12:17:37 -0700
To: Adobe Systems <vhardy@adobe.com<mailto:vhardy@adobe.com>>
Cc: Chris Marrin <cmarrin@apple.com<mailto:cmarrin@apple.com>>, "public-fx@w3.org<mailto:public-fx@w3.org>" <public-fx@w3.org<mailto:public-fx@w3.org>>
Subject: Re: Update on CSS shaders security issue

2012/4/21 Vincent Hardy <vhardy@adobe.com<mailto:vhardy@adobe.com>>:
Hi Chris,

Thanks for your feedback and I think it is good to have these discussions. I
hope you won't mind the top-reply, as I am trying to organize things to
clarify my answer. I am organizing it around the points you bring up and I
hope I did not miss anything. Let me preface this by saying that I would
much prefer not having the restriction I proposed, but at this point, I
think this is the right way to proceed.

Unproven attacks?

The write-up
at http://www.w3.org/Graphics/fx/wiki/CSS_Shaders_Security discusses
different types of security concerns. However, in all cases, the issues
boils down to a) having access to sensitive data (either third party data as
in your iframe example or user agent data such as visited links) and b)
having a 'communication channel' which allows the shader to send data to an
accomplice script.

We have been able to demonstrate internally that a visited link attach was
possible. Essentially, the technique is the same as was demonstrated on
WebGL shaders before. It is not hard to implement. That demonstration
convinced our team that the threat is real and we cannot allow shaders to
vary their execution time in a detectable way.

Are shaders still useful with the proposed restrictions?

I respectfully disagree with the point that the restriction nullifies the
usefulness of CSS shaders. Here is why:

1) vertex shaders are extremely useful even without texture access. They do
not need a very dense mesh. Most of the examples we created have excellent
visual results with modest size meshes (20x20 to 50x50). Compared to the
number of pixels fragment shaders process, this is low density. All kinds of
very nice effects can be achieved with this. Actually, I think this is a the
part of CSS shaders that we should strive to make most progress on quickly,
because there is no good fallback solution for what it offers.

2) fragment shaders are, I agree, restricted quite severely with this
proposal. However, there are two important points to make:
- filters that apply a uniform operation on an image do not require a
shader. Granted, shader may often do multiple things in combination and that
is useful / efficient, but the functionality is not fully gone. There are
SVG filter graphs and there are filter shorthands.
- we could extend the definition of what fragment shaders can do. For
example, Alex internally has been suggesting that the restricted fragment
shaders could produce a convolution matrix which the implementation would
then use to produce the fragment color input to the shader. That is an
alternate way of writing the shader and defining the restriction. My point
is that we can work on the fragment shader restrictions if we find the
current one is too limiting. But even then, and again looking at all the
examples we have come up with, I think there is a lot of very useful things
we can do (light maps being one important one).

Could we ever remove the proposed restriction?

We have worked hard internally at Adobe on a solution to the timing attacks
that we had been able to reproduce. We were successful in deflecting that
particular attack. See the work suggested by Gregg that Max and Alex did
at:

http://www.w3.org/Graphics/fx/wiki/CSS_Shaders_Security#Method_H:_Tainting_shader_code_branches
http://code.google.com/p/mvujovic/wiki/ShaderControlFlowAnalysis

However, this does not protect against attacks that would exploit the
varying execution time of floating points as was raised recently and is a
known performance issue
(see http://en.wikipedia.org/wiki/Denormal_number#Performance_issues).

Our current approach at Adobe is to first implement shaders with the
restrictions because we think this is a) still a huge step forward
(especially because it brings in vertex shaders) and b) a relatively low
hanging fruit to implement. Once we have that in, we are planning on
actually testing out the performance issues with floating point operations.
Hopefully, we can gather evidence that the threat is not valid, but that
will take time and research.

The discussions I have had with people who know a lot more than me on this
topic is that the floating point units on CPUs are known to take slow paths
in some conditions and if a shader implementation was to use these floating
point units, an attack would be easy. However, in a lot of cases, it seems
that floating point computations are moving to SSE (on Intel
architectures, http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) and I
do not know how bad the problem is there. We need to do a lot of research to
see if the security restriction can be lifted: we need to understand more
about the software fallbacks and do more testing on different CPU and GPU
architectures.

Notice that SSE is more than SIMD. SSE also provides a full
replacement for the scalar (non-vector) instructions of the old x87.

The attached program tests this. It uses the Eigen matrix/SIMD library
which is just c++ headers (http://eigen.tuxfamily.org). All it does is
4x4 float32 matrix products.

I'm using GCC 4.6 on linux x86-64. SSE2 is implied by default.

Let's first test using x87 (no SSE) instructions:

##### 15:03:35 ~$ g++ -mfpmath=387 -DEIGEN_DONT_VECTORIZE
-DCONSTANT=0.f/0.f a.cpp -O3 -o a -I eigen && time ./a
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan

real    0m12.526s
user    0m12.505s
sys     0m0.004s
##### 15:04:03 ~$ g++ -mfpmath=387 -DEIGEN_DONT_VECTORIZE
-DCONSTANT=0.f a.cpp -O3 -o a -I eigen && time ./a
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

real    0m0.073s
user    0m0.068s
sys     0m0.004s


So on x87, we have a really large speed difference between NaN and
regular values.

Let's now test SSE scalar instructions instead of x87:


##### 15:04:09 ~$ g++ -DEIGEN_DONT_VECTORIZE -DCONSTANT=0.f/0.f a.cpp
-O3 -o a -I eigen && time ./a
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan

real    0m0.049s
user    0m0.040s
sys     0m0.004s
##### 15:04:22 ~$ g++ -DEIGEN_DONT_VECTORIZE -DCONSTANT=0.f a.cpp -O3
-o a -I eigen && time ./a
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

real    0m0.048s
user    0m0.044s
sys     0m0.000s



There isn't a conclusive speed difference anymore.

Let's now test still with SSE but with the SIMD instructions:


##### 15:04:30 ~$ g++ -DCONSTANT=0.f/0.f a.cpp -O3 -o a -I eigen &&
time ./a-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan

real    0m0.025s
user    0m0.024s
sys     0m0.000s
##### 15:04:37 ~$ g++ -DCONSTANT=0.f a.cpp -O3 -o a -I eigen && time ./a
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

real    0m0.026s
user    0m0.028s
sys     0m0.000s


Still no speed difference between NaN and regular.

This suggests that the speed differences between Nan and regular
values may be specific to x87 instructions.

Anyhow, I would be very wary of letting the security of a Web standard
rely on such fine technical details.

Cheers,
Benoit



I should note that we did run several experiments on GPUs (while working on
control flow analysis) and so far, we have not been able to see detectable
execution times on arithmetic operations. But more research is needed to
have a definite position. In the meanwhile, imposing restrictions allow us
to proceed.

Relation to CORS

You point out that we should look at restricting shading third party content
instead of restricting access to pixel values. Unfortunately, this does not
solve the problem of access to user agent data (visited links). This is why
we have focused on restricting access to pixel values and/or removing the
ability to communicate from the shaders.

Should we move to a different approach?

Your email suggest that may be we should move to fixed function shaders. For
fragment shaders, that may be a good solution, but I am not clear how this
would be essentially different from the filter graphs SVG filters already
provide. For vertex shaders, I think we definitely need to keep the
functionality and approach we have taken.

I hope this clarifies our approach,
Kind regards,
Vincent

On Apr 21, 2012, at 8:02 AM, Chris Marrin wrote:


I just wanted to toss my 2 cents in here. First let me say that while I'm
still editor of the WebGL spec, I'm no longer in the WebKit group. So my
observations about CSS shaders are as an interested 3rd party. And let me
also say that I have great respect for all the work this group has done.

If I am reading your proposal right you're saying that we will have no
access to the texture we're filtering in the shaders. If so, that would seem
to nullify the usefulness of this feature. The two examples you give (vertex
shader-based image warping and fragment shader "lighting") are really the
only two effects that would be practical. Vertex shader warping is mildly
interesting, but will need very dense meshes to get really interesting
effects. But you're really only allowing fragment shaders to be image
generators which are then blended with the source image. That doesn't seem
interesting at all. With this restriction you lose out on any fragment
shader based image warping, blurring, and almost all interesting (IMHO) use
cases.

That leads me to ask, is it worth it? Maybe the energies of this group would
be better spent focusing on more advanced fixed function shaders. For
instance, adding the majority of the CoreImage filters and the ability to
combine filters with a graph topology would at least give you access to a
wide variety of advanced filtering techniques.

Moving down this path takes away an incredibly powerful tool from web
authors. Another implication is that WebGL will never be able to access
rendered page content, cutting out many interesting and powerful effects,
which have already been demoed. It is, in effect, stifling advancement of
the web platform due to non-technical privacy concerns.

On several occasions I've brought up the point that all these concerns are
based on unproven attack vectors. That point has been repeatedly shot down
with claims that it has been proven, referencing some vague numbers that
show it's possible for a shader to take different amounts of time based on a
pixel's color. All that might be true, but never have I seen an actual
example of an attack. Where is the site I can go to where I can type a
string into a text box and within a few seconds the site tells me what I
typed merely by examining the image of what I typed? Maybe such a thing is
possible, but it seems wrong to cut out a powerful feature like this before
proving it. Once it is proven, some browser vendor might come up with a
technique to thwart such an attack. Then it becomes an arms race between
clever attackers and clever defenses. But isn't that what the web has been
all about for many years?

And maybe this group, rather than looking at ways to make it impossible to
deduct the value of pixels from a shader, should instead look at making it
impossible for an attacker to get at the pixels of a legitimate site in the
first place. Would preventing frame based content from running shaders solve
that problem? I don't know, but it seems like its important to understand
how an attack would work end-to-end and then stop it somewhere other than in
the fragment shader.

I understand that these points probably won't be any more well received now
than they have in the past. But I felt the need to say them. This really is
the future of the web. If these problems can't be solved now, it doesn't
bode well for things to come.

On Apr 18, 2012, at 10:54 PM, Vincent Hardy wrote:

Hello,

Since the original proposal on CSS shaders, there have been discussions on
this list and some related discussion on the WebGL mailing list at Khronos.

Following the most recent findings in efforts to make CSS shaders secure, I
have updated the page that summarizes the proposed security measure that
looks the most reasonable. The other measures that were considered are also
documented and a summary of why there did not fully meet the needs is also
provided.

The short description of the proposal is that it removes access to the
rendered content from the shaders. This is not an issue for vertex shaders
(at least for a wide set of use cases). For fragment shaders, the result
produced by the shader will be combined with the rendered content, but this
combination step is not controlled by the shader, it is controlled by the
implementation.

For example, a vertex shader that produces a flapping flag effect will not
be affected by the restriction because it does not need access to the
texture. A fragment shader that computes a lighting effect will compute a
light map that the implementation will then multiply with the original
texture. Here again, the shader does not access the rendered texture.

I believe that this is a good approach and while it reduces some of the
functionally, it also addresses the new security concerns CSS shaders
raised.

Please see the detailed description of the approach and examples of how a
technology like ANGLE could be used for an efficient implementation:

http://www.w3.org/Graphics/fx/wiki/CSS_Shaders_Security

Kind regards,
Vincent Hardy


-----
~Chris
cmarrin@apple.com<mailto:cmarrin@apple.com>

Received on Tuesday, 24 April 2012 16:20:56 UTC