2011-01-12 34 views
15

Tengo un sitio que se ejecuta en pixie.strd6.com y las imágenes alojadas a través de Amazon S3 con un CNAME para images.pixie.strd6.com.HTML5 Canvas getImageData y política de mismo origen

Me gustaría ser capaz de dibujar estas imágenes a un canvas de HTML5 y llame al método getImageData pero lanza Error: SECURITY_ERR: DOM Exception 18

He intentado fijar window.domain = "pixie.strd6.com", pero que no tiene ningún efecto.

Además, $.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)}) también genera un error: XMLHttpRequest cannot load http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982 . Origin http://pixie.strd6.com is not allowed by Access-Control-Allow-Origin.

lienzo Idealmente HTML5 no bloquearía llamando getImageData de subdominios. He buscado establecer un encabezado Access-Control-Allow-Origin en S3, pero no lo he logrado.

Cualquier ayuda o solución alternativa son muy apreciadas.

+34

Esta misma política de origen es la cosa más tonta nunca . Si soy un componente malicioso de JavaScript y quiero cargar datos maliciosos, solo incluiré una etiqueta de script arbitraria en la página, sin leer "s3kri7 c0mm4nd5" a partir de los datos de imagen. Las únicas personas que quieren leer datos de imagen son desarrolladores del lado del cliente. En cuanto a robar "datos de imágenes secretas" de vpn, si su sitio ya ha sido descodificado, el registro de teclas será mucho más devastador. Toda esta "protección" sirve para agravar a los desarrolladores legítimos que intentan obtener JavaScript para hacer las tareas más sencillas. –

+7

El SOP protege contra un vector de ataque legítimo aquí.Supongamos que tiene un álbum de fotos privado en un sitio para compartir fotos (o ver imágenes almacenadas en su banca en línea): sin protección de lona sucia, * cualquier página en la Web * que visite tendría el poder de captar esas imágenes si conocieran el URL e ingresó, porque las solicitudes enviadas desde '' etiquetas ** usan sus cookies **. El problema aquí no está comprometido con los sitios XSS; el problema es que * cualquier página en la Web * podría buscar y leer imágenes en un lienzo utilizando sus cookies de autenticación. – apsillers

+2

** tl; dr: ** Tal como está ahora, cualquier sitio de dominios cruzados puede * mostrar * sus imágenes requeridas por autenticación (fotos privadas, imágenes de cheques, etc.) en una etiqueta '', pero, gracias a la SOP, no pueden * leer * el contenido de esas imágenes en un lienzo para, por ejemplo, guardarlas en un servidor. – apsillers

Respuesta

6

Amazon recently announced CORS support

We're delighted to announce support for Cross-Origin Resource Sharing (CORS) in Amazon S3. You can now easily build web applications that use JavaScript and HTML5 to interact with resources in Amazon S3, enabling you to implement HTML5 drag and drop uploads to Amazon S3, show upload progress, or update content. Until now, you needed to run a custom proxy server between your web application and Amazon S3 to support these capabilities.

How to enable CORS

To configure your bucket to allow cross-origin requests, you create a CORS configuration, an XML document with rules that identify the origins that you will allow to access your bucket, the operations (HTTP methods) will support for each origin, and other operation-specific information. You can add up to 100 rules to the configuration. You add the XML document as the cors subresource to the bucket.

1

Este comportamiento es por diseño. Según la especificación de HTML5, tan pronto como dibuja una imagen de origen cruzado en un lienzo, está sucia y ya no puede leer los píxeles. La coincidencia de origen compara el esquema, el host totalmente calificado, y en los navegadores que no son IE, el puerto.

+0

¿Entonces la solución es involucrar un proxy a través de mi servidor web? –

+4

Sí, el código del servidor proxy las imágenes funcionarán, pero es triste que tengamos que confiar en algo que no sería necesario. Al menos deberían implementar políticas de dominio cruzado a través de un archivo xml en el servidor de destino, como se hizo con flash. – Omiod

3

Una posible solución es usar nginx para actuar como un proxy. Aquí se explica cómo configurar las URL que van al http://pixie.strd6.com/s3/ para pasar a S3, pero el navegador aún puede creer que no es de dominio cruzado.

location /s3/ { 
    proxy_pass http://images.pixie.strd6.com/; 
} 
2

Recientemente, me encontré con $.getImageData, por Max Novakovic. La página incluye un par de demostraciones claras de buscar y operar en fotos de Flickr, junto con algunos ejemplos de código.

Le permite buscar una imagen en formato manipulable por JavaScript desde un sitio arbitrario. Funciona al agregar un script a la página. El script luego solicita la imagen de un servidor de Google App Engine. El servidor obtiene la imagen solicitada y la retransmite a base64 al script. Cuando el script recibe el base64, pasa los datos a una devolución de llamada, que luego puede dibujar sobre un lienzo y comenzar a jugar con él.

2

En el pasado, Amazon S3 no le permitía modificar o agregar los encabezados HTTP de control de acceso-permitir-origen y acceso-controlar-permitir-credenciales, así que podría haber sido mejor cambiar a un servicio diferente como Rackspace Cloud Files o algún otro servicio que sí lo hace.

Agregar o modificar las cabeceras HTTP como este:

access-control-allow-origin: [your site] 
access-control-allow-credentials: true 

Ver http://www.w3.org/TR/cors/#use-cases para más información.

El uso de un servicio que le permite modificar los encabezados HTTP resuelve por completo el mismo problema de origen.

3

Si está usando PHP, puede hacer algo como:

function fileExists($path){ 
     return (@fopen($path,"r")==true); 
    } 
    $ext = explode('.','https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg'); 
    if(fileExists('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg')){ 
     $contents = file_get_contents('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg'); 
     header('Content-type: image/'.end($ext)); 
     echo $contents; 
    } 

y accede a la imagen mediante el uso de ese archivo php, como si el archivo se llama generateImage.php que puede hacer <img src="http://GENERATEPHPLOCATION/generateImage.php"/> y la imagen externa url puede ser un parámetro GET para el archivo

2

Para las personas que no usan S3 pueden intentar crear un proxy de imagen que codifique el archivo de imagen y lo envuelva en un objeto JSON.

Luego puede usar JSONP, que admite dominio cruzado para buscar el objeto JSON y asignar los datos de imagen a img.src.

Escribí un código de muestra del servidor proxy de imagen con Google App Engine. https://github.com/flyakite/gae-image-proxy

el objeto regresa JSON en el formato como este

{ 
    'height': 50, 
    'width' : 50, 
    'data' : 'data:image/jpeg;base64,QWRarjgk4546asd...QWAsdf' 
} 

El 'datos' son los datos de imagen en formato de base 64. Asignarlo a una imagen.

img.src = result.data; 

La imagen ahora es "limpia" para su lienzo.

2

para editar sus permisos depósito de S3:

1) Iniciar sesión en AWS Management Console y abra la consola de Amazon S3 en https://console.aws.amazon.com/s3/

2) En la lista Valdés, abra el cubo cuyas propiedades desea para ver y haga clic en "agregar configuración CORS"

amazon-screen-shot

3) Escribir las reglas que están dispuestos a añadir entre las etiquetas <CORSConfiguration>

<CORSConfiguration> 
    <CORSRule> 
    <AllowedOrigin>*</AllowedOrigin> 
    <AllowedMethod>GET</AllowedMethod> 
    <MaxAgeSeconds>3000</MaxAgeSeconds> 
    <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
</CORSConfiguration> 

se puede aprender más acerca de las reglas en: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) Especificar crossorigin = 'anónimo' en la imagen que va a utilizar en su lienzo

Cuestiones relacionadas