This page is a work in progress as I track down the problem. Please add comments if you have anything that might be helpful.
The problem appears to be with Java applets that use double buffering (performing all drawing operations to an off-screen image and then displaying that image).
Certain applets (it seems to be large sized ones) are displaying twice, one on top of the other, and the top copy is the correct size but it showing a corrupted image formed from random parts of images that were already in the browser's memory.
Browsers affected:
Firefox
Safari
Chrome
Opera
The same applet runs fine in all browsers on Windows XP and Debian Squeeze.
OSX versions known to be affected:
Mac OS 10.7.5
Mac OS 10.8.2
Java versions exhibiting graphics corruption:
Java 7 update 10
Java 7 update 11
Java 7 update 13
Java applet corruption on JRE 7 update 10 on Mac OSX
Java applet corruption on JRE 7 update 10 on Mac OSX
Update 28/12/2012: The following code reproduces the corruption:
package com.chrisnewland.applet;

import java.applet.*;

import java.awt.*;
import java.awt.image.BufferedImage;

public class SimpleApplet extends Applet implements Runnable
{
   private int width;
   private int height;

   private BufferedImage bufferImage;
   private Graphics2D bufferGraphics;

   private boolean running = false;

   private boolean nextImageReady = false;

   @Override
   public void init()
   {
       setSize(800, 2000);

       width = this.getSize().width;
       height = this.getSize().height;

       GraphicsEnvironment env = GraphicsEnvironment
               .getLocalGraphicsEnvironment();
       GraphicsDevice device = env.getDefaultScreenDevice();
       GraphicsConfiguration config = device.getDefaultConfiguration();
       bufferImage = config.createCompatibleImage(width, height);

       bufferGraphics = (Graphics2D) bufferImage.getGraphics();
   }

   @Override
   public void start()
   {
       running = true;
       new Thread(this).start();
   }

   @Override
   public void stop()
   {
       running = false;
   }

   @Override
   public void update(Graphics g)
   {
       if (!nextImageReady)
       {
           return;
       }

       g.drawImage(bufferImage, 0, 0, null);

       nextImageReady = false;

       try
       {
           Thread.sleep(20);
       }
       catch (InterruptedException ie)
       {
       }

   }

   @Override
   public void paint(Graphics g)
   {
       update(g);
   }

   @Override
   public void run()
   {
       int x = 0;

       try
       {
           while (running)
           {
               if (!nextImageReady)
               {
                   bufferGraphics.setColor(Color.white);
                   bufferGraphics.fillRect(0, 0, width, height);

                   bufferGraphics.setColor(Color.black);
                   bufferGraphics.fillRect(x, height / 4, 200, 200);

                   x += 4;

                   if (x > width)
                   {
                       x = 0;
                   }

                   repaint();

                   nextImageReady = true;
               }
               else
               {
                   Thread.sleep(1);
               }
           }
       }
       catch (Exception ie)
       {
           ie.printStackTrace();
       }
   }
}