Hi Brian, Steve,
I believe you could fish out the texel values with a timer-based
attack even without vertex texture support: Just draw N screen-sized quads,
where N is the number of texels in your secret texture, using a fragment shader
that samples the same texel for every fragment and consumes time in proportion
to the texel value (which Steve already showed how to do). If you have a very
fast GPU and/or bad timers, just increase the size of the quad and/or draw it
several times until you get measurable differences.
As a newcomer to web development, I keep wondering if these
restrictions on image data access are genuinely necessary. They are a giant
pain in the bottom for the ordinary developer, yet there are ways for attackers
to go around them, so why bother?
firstname.lastname@example.org [mailto:email@example.com] On
Behalf Of ext Brian Cornell
Sent: 6. lokakuuta 2010 9:14
To: Steve Baker
Cc: public webgl; Chris Marrin
Subject: Re: [Public WebGL] Proposed change to WebGL spec section 4.2
(Security Origin Restrictions)
Back on topic though, your example hack doesn't change whether we have finer
grained origin control or not, as that will work with the current method.
Your hack would argue for even stricter rules (don't allow vertex textures
and don't allow discard, or don't allow tainted textures to ever be used) or
giving up on it since somebody will find a way around it anyway.
On Oct 5, 2010 8:28 PM, "Steve Baker" <firstname.lastname@example.org> wrote:
> Brian Cornell wrote:
>> If I understand the WebGL shader limitations correctly, you black hat
>> solution would not work because loops that can't be statically
>> unrolled are not allowed. So you could not use a loop based on the
>> texel value.
> If you did a pixel 'discard' inside an 'if' statement many modern cards
> would do an early-out of the shader if all of the adjacent pixels
> terminated early. No amount of legalese in the spec will prevent that
> from happening if that's what the hardware actually does:
> for ( i = 0 ; i < 256 ; i++ )
> if ( i > texelBrightness*255 )
> discard ;
> read a random texel out of a huge map ;
> But it doesn't matter...I just thought of something even easier. Even
> if the vertex and pixel shaders take absolutely the same amount of time
> no matter what - I can STILL just do this at the end if the vertex shader:
> gl_Position = vertexPosition.xy * texelBrightness ;
> ...then I bind the texture to a vertex shader sampler and draw a large
> quad in the center of the screen.
> The size of the quad will be proportional to the square of the texel
> brightness - and the number of pixels we'll draw will be roughly
> proportional to the brightness - and with finite frame buffer memory
> speeds that's got to impact the pixel processing time in a sufficiently
> predictable way for this hack to work. For a useful exploit we might
> only need to be able to read a 100x20 texel patch of white text on a
> black background and we've stolen someone's credit card number. You'd
> only need to distinguish black from white...a simple timing threshold
> would suffice. Text is pretty readable even in the presence of
> considerable noise - so random timing variations would be little
> obstacle to the determined bad guy.
> So there are plausible exploits even with readTexels and occlusion
> culling completely disabled.
> The trouble is that this is the kind of thing that 10 minutes of me
> thinking about it can turn up. Bad guys trying to recover passwords or
> credit card numbers will be thinking about this for months or even years
> - there are an unbelievable number of tiny chinks in the armor that
> could possibly be exploited.
> -- Steve