HTML5 Canvas getImageData и та же политика происхождения

У меня есть сайт, работающий по адресу pixie.strd6.com, и изображения, размещенные на Amazon S3, с CNAME для images.pixie.strd6.com.

Я хотел бы иметь возможность рисовать эти изображения на холсте HTML5 и вызывать метод getImageData, но он выдает Error: SECURITY_ERR: DOM Exception 18

Я попытался установить window.domain = "pixie.strd6.com", но это не помогло.

Кроме того, $.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)}) также выдает ошибку: 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.

В идеале холст HTML5 не блокировал бы вызов getImageData из поддоменов. Я пытался настроить заголовок Access-Control-Allow-Origin в S3, но безуспешно.

Любая помощь или обходные пути приветствуются.


person Daniel X Moore    schedule 12.01.2011    source источник
comment
Та же самая политика происхождения — самая глупая вещь на свете. Если я являюсь вредоносным фрагментом JavaScript и хочу загрузить вредоносные данные, я просто включу произвольный тег скрипта на страницу, а не прочитаю s3kri7 c0mm4nd5 из данных изображения. Единственные люди, которые хотят читать данные изображения, — это разработчики на стороне клиента. Что касается кражи сверхсекретных данных изображения из VPN, если ваш сайт уже подвергся xss, то кейлоггинг будет гораздо более разрушительным. Вся эта защита служит тому, чтобы раздражать законных разработчиков, пытающихся заставить JavaScript выполнять самые простые задачи.   -  person Daniel X Moore    schedule 13.01.2011
comment
Здесь SOP защищает от законного вектора атаки. Предположим, у вас есть личный фотоальбом на сайте обмена фотографиями (или проверьте изображения, хранящиеся в вашем онлайн-банкинге): без защиты от грязного холста любая страница в Интернете, которую вы посещаете, могла бы захватить эти изображения, если они знали URL-адрес и вы вошли в систему, потому что запросы, отправленные из <img> тегов, используют ваши файлы cookie. Проблема здесь не в скомпрометированных XSS-сайтах; проблема в том, что любая страница в Интернете может получать и читать изображения на холсте, используя ваши файлы cookie для аутентификации.   -  person apsillers    schedule 19.12.2012
comment
tl;dr: В настоящее время любой междоменный сайт может отображать ваши изображения, необходимые для аутентификации (частные фотографии, контрольные изображения и т. д.) в теге <img>, но, благодаря SOP, они не могут прочитать содержимое этих изображений на холсте, чтобы, например, сохранить их на сервере.   -  person apsillers    schedule 19.12.2012
comment
Я пришел к выводу, что это действительно защищает от некоторых законных векторов атак. Теперь, когда поддержка CORS становится все более распространенной, можно корректно разрешать доступ к ресурсам, размещенным во внешних доменах. Это все еще проблема для среднего разработчика, потому что цена/выгода от дополнительной безопасности для фотографий кошек невелика, но важно, чтобы Интернет оставался безопасным для банков, которые необъяснимым образом отображают конфиденциальную информацию на изображениях.   -  person Daniel X Moore    schedule 20.12.2012
comment
интересно, что будет, если я сделаю document.imd={};, потом document.imd[elementId] = document.getElementById(elementId).getContext("2d").getImageData(0,0,img.width, img.height); и только после этого запущу document.getElementById(elementId).getContext("2d").drawImage(img,0,0). Что тогда будет делать браузер, если я получу ссылку на данные изображения ДО того, как они будут испорчены?   -  person Arioch 'The    schedule 08.05.2013


Ответы (9)


Amazon недавно анонсированная поддержка CORS

Мы рады объявить о поддержке совместного использования ресурсов между источниками (CORS) в Amazon S3. Теперь вы можете легко создавать веб-приложения, использующие JavaScript и HTML5 для взаимодействия с ресурсами в Amazon S3, что позволяет реализовывать загрузку HTML5 методом перетаскивания в Amazon S3, отображать ход загрузки или обновлять контент. До сих пор вам нужно было запускать настраиваемый прокси-сервер между вашим веб-приложением и Amazon S3 для поддержки этих возможностей.

Как включить CORS

Чтобы настроить корзину для разрешения запросов между источниками, вы создаете конфигурацию CORS, XML-документ с правилами, определяющими источники, которым вы разрешаете доступ к своей корзине, операции (методы HTTP), которые будут поддерживаться для каждого источника, и другие операции. -конкретная информация. В конфигурацию можно добавить до 100 правил. Вы добавляете XML-документ в качестве подресурса cors в корзину.

person Daniel X Moore    schedule 02.11.2012

Одним из возможных решений является использование nginx в качестве прокси. Вот как настроить URL-адреса, идущие на http://pixie.strd6.com/s3/ для прохождения на S3, но браузер все еще может считать, что это не междоменный домен.

location /s3/ {
  proxy_pass http://images.pixie.strd6.com/;
}
person Daniel X Moore    schedule 05.02.2011

Если вы используете PHP, вы можете сделать что-то вроде:

    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;
    }

И получите доступ к изображению, используя этот файл php, например, если файл называется generateImage.php, вы можете сделать <img src="http://GENERATEPHPLOCATION/generateImage.php"/>, а URL-адрес внешнего изображения может быть параметром получения для файла

person milind desai    schedule 27.06.2012

Недавно я наткнулся на $.getImageData Макса Новаковича. На этой странице есть несколько демонстраций извлечения и работы с фотографиями Flickr, а также несколько примеров кода.

Он позволяет вам получить изображение в форме, управляемой с помощью JavaScript, с произвольного сайта. Он работает путем добавления скрипта на страницу. Затем сценарий запрашивает изображение с сервера Google App Engine. Сервер извлекает запрошенное изображение и передает его сценарию, преобразованному в base64. Когда скрипт получает base64, он передает данные обратному вызову, который затем может нарисовать их на холсте и начать возиться с ними.

person George    schedule 07.03.2011

В прошлом Amazon S3 не позволял вам изменять или добавлять HTTP-заголовки access-control-allow-origin и access-control-allow-credentials, поэтому, возможно, было лучше переключиться на другой сервис, такой как Rackspace Cloud Files или какой-либо другой. другой сервис, который делает.

Добавьте или измените заголовки HTTP следующим образом:

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

См. http://www.w3.org/TR/cors/#use-cases для получения дополнительной информации.

Использование службы, позволяющей изменять заголовки HTTP, полностью решает ту же проблему происхождения.

person Community    schedule 15.02.2012

Для людей, которые не используют S3, можно попытаться создать прокси-сервер изображения, который кодирует файл изображения и заключает его в объект JSON.

Затем вы можете использовать JSONP, который поддерживает междоменный доступ, чтобы получить объект JSON и назначить данные изображения img.src .

Я написал пример кода прокси-сервера изображений с помощью Google App Engine. https://github.com/flyakite/gae-image-proxy

Объект JSON возвращается в таком формате

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

«Данные» — это данные изображения в формате base64. Назначьте его изображению.

img.src = result.data;

Теперь изображение «чисто» для вашего холста.

person Shih-Wen Su    schedule 27.03.2013

Чтобы изменить права доступа к корзине S3:

1) Войдите в Консоль управления AWS и откройте консоль Amazon S3 по адресу https://console.aws.amazon.com/s3/

2) В списке сегментов откройте сегмент, свойства которого вы хотите просмотреть, и нажмите «добавить конфигурацию CORS».

amazon-screen-shot

3) Напишите правила, которые вы хотите добавить между тегами <CORSConfiguration>

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

Вы можете узнать больше о правилах по адресу: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) Укажите crossorigin='anonymous' на изображении, которое вы будете использовать на холсте.

person Flavio Wuensche    schedule 12.11.2013

Такое поведение является особенностью. В соответствии со спецификацией HTML5, как только вы рисуете изображение из разных источников на холсте, оно становится грязным, и вы больше не можете читать пиксели. Сопоставление происхождения сравнивает схему, полностью определенный хост и порт в браузерах, отличных от IE.

person EricLaw    schedule 12.01.2011
comment
Да, серверный код для проксирования изображений будет работать, но грустно, что нам приходится полагаться на то, что было бы не нужно. Они должны по крайней мере внедрить междоменные политики через xml-файл на целевом сервере, как это было сделано с флэш-памятью. - person Omiod; 13.01.2011

Только что столкнулся с такой же проблемой. Я узнал о CORS, который может быть полезен.

http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#14

У меня это не сработало, так как я пытаюсь манипулировать изображением с Flickr. Итак, я все еще ищу решение.

person Gustavo    schedule 12.12.2011