Browser Canvas Cors Support for Cross Domain Loaded Image Manipulation

Browser Canvas CORS Support for Cross Domain Loaded Image Manipulation

Test Results: Bad News, it appears to only work in Chrome.
All other browsers (including Android Mobile) give an error like this:

Failed: DOM Exception: SECURITY_ERR (18)

Mobile Devices I tested Android (samsung galaxy kernel version 2.6.32.9), Iphone and IPAD V1 and it failed in all three.

You can test your own mobile device with this URL:
http://maplarge.com/CrossOriginImageTest.html

The Test Script:

  <!DOCTYPE html>
<html>
<head>
<title>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</title>
<script type="text/javascript">
function initialize() {

//will fail here if no canvas support
try {
var can = document.getElementById('mycanvas');
var ctx = can.getContext('2d');
var img = new Image();
img.crossOrigin = '';
//domain needs to be different from html page domain to test cross origin security
img.src = 'http://lobbydata.com/Content/images/bg_price2.gif';
} catch (ex) {
document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex.Message + "</span>";
}

//will fail here if security error
img.onload = function () {
try {
var start = new Date().getTime();
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
var url = can.toDataURL(); // if read succeeds, canvas isn't dirty.
//get pixels
var imgd = ctx.getImageData(0, 0, img.width, img.width);
var pix = imgd.data;
var len = pix.length;
var argb = []; //pixels as int
for (var i = 0; i < len; i += 4) {
argb.push((pix[i + 3] << 24) + (pix[i] << 16) + (pix[i + 1] << 8) + pix[i + 2]);
}
var end = new Date().getTime();
var time = end - start;
document.getElementById("results").innerHTML = "<span style='color:Green;'>" +
"Success: Your browser supports CORS for cross domain images in Canvas <br>"+
"Read " + argb.length+ " pixels in "+ time+"ms</span>";
} catch (ex) {
document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex + "</span>";
}

}

}
</script>
</head>
<body onload="initialize()">
<h2>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</h2>
<h2><a href="http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html">What is CORS Image Security?</a></h2>
<h1 id="results" style="color:Orange;">Testing...</h1>
<canvas id="mycanvas"></canvas>
<br />
<a href="/Example/List">More Examples</a>
</body>
</html>

Unable to load image from localhost url because of cross origin

An origin is a domain, plus a scheme and port number.

you use two different port 44376 and 44377

44376 only access to 44377 when on the header of 44377 response was something like this

Access-Control-Allow-Origin: https://localhost:44376

and how to add this header to your responses, it depends on your server

you can see Apache, IIS6, IIS7, PHP and ASP.NET in

https://www.aurigma.com/docs/us8/enabling-cross-origin-resource-sharing.htm

NodeJS in

How to enable cross-origin resource sharing (CORS) in the express.js framework on node.js

XAMPP in

How do I enable cross-origin resource sharing on XAMPP?

Good luck ☺

HTML5 Canvas cross-domain security issue

I don't think the security issue is in manipulation -- it's in reading or capturing a screenshot from another page. A variation of the theme is reading raw pixels from an image, that is intended to be displayed, but not for OCR... (e.g. some bank account secrets.)

http://www.contextis.com/resources/blog/webgl2/

From the start WebGL implementations suffered from non-conformance to specifications, which probably led Microsoft to develop alternative technology on IE and simultaneously claim that providing an access to GPU with a web page is a high risk by itself.

cross-domain image for three.js (canvas/webGL), proxy?

EUREKA!!! loox like proxy's the way to go,
this did the trick :)

<?php
// PHP Proxy
// Responds to both HTTP GET and POST requests
//
// Author: Abdul Qabiz
// March 31st, 2006
//

// Get the url of to be proxied
// Is it a POST or a GET?
$url = ($_POST['url']) ? $_POST['url'] : $_GET['url'];
$headers = ($_POST['headers']) ? $_POST['headers'] : $_GET['headers'];
$mimeType =($_POST['mimeType']) ? $_POST['mimeType'] : $_GET['mimeType'];

//Start the Curl session
$session = curl_init($url);

// If it's a POST, put the POST data in the body
if ($_POST['url']) {
$postvars = '';
while ($element = current($_POST)) {
$postvars .= key($_POST).'='.$element.'&';
next($_POST);
}
curl_setopt ($session, CURLOPT_POST, true);
curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
}

// Don't return HTTP headers. Do return the contents of the call
curl_setopt($session, CURLOPT_HEADER, ($headers == "true") ? true : false);

curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

// Make the call
$response = curl_exec($session);

if ($mimeType != "")
{
// The web service returns XML. Set the Content-Type appropriately
header("Content-Type: ".$mimeType);
}

echo $response;

curl_close($session);

?>

Images loaded through JavaScript are throwing me CORS errors even though it's enabled

Turns out that if you have the crossOrigin="anonymous" attribute on the image, the browser won't like it if the image doesn't return a proper CORS header.

CORS settings for images in canvas

Even though, this is 4 month old question, i would like to help others who fetched S3, CORS and HTML canvas issues by putting here a reference to a working solution.

Amazon S3 will send Cross-Origin headers only if was explicitly asked for (see CORS specs). It means that the client must ask for them explicitly in the HTTP request. The expected behavior is that the client will specify the host-name inside the "Origin: host-name" header in the request, and the server will check if it should share the resources with the specific origin name. What is important to understand here, if your client is a Web-Browser, it will not send this header for no reason.

This is the way how the Cross-Domain ajax requests works. Recently support added for some other resources like fonts and images.

Images:
HTML5 added Cross-Origin support for images in HTML tags and Javascript... Use the crossOrigin attribute on images and the browser will fetch the resource as a Cross-Origin resource (it will add the Origin header to the HTTP request) link to the original post.

The crossorigin attribute is a CORS settings attribute. Its purpose is
to allow images from third-party sites that allow cross-origin access
to be used with canvas.

read more on MDN

i also fetched similar issue, if you can rely on HTML5 support on the client side, use that solution!

Why CORS on Images with HTML Canvas?

This protects users from having private data exposed by using images to pull information from remote web sites without permission.

Source: MDN

Canvas image crossplatform insecure error

An updated look at Html5 Canvas with Cross-Domain content.

Here is an updated look at how cross-domain content affects the html5 canvas and how to work within the security restrictions that apply to cross-domain content

An update is useful today (2016-Jan) because there are several new(ish) methods to allow cross-domain images to be drawn to canvas without tainting the canvas.

Drawing cross-domain content on html5 canvas will cause it to be "tainted"

You can draw an image from another domain on the canvas and it will display on the canvas. Accessing resources from another domain is called "Cross Origin Resource Sharing" -- and is generally known as "CORS" for short.

Drawing CORS content (f.ex: images) will cause the canvas to be "tainted" for security reasons.

If the canvas is tainted you cannot use these canvas & context methods:

  • context.getImageData to fetch the pixel data on the canvas
  • canvas.toDataURL to export the canvas as an image

You can't "trick" canvas into violating its CORS security restrictions -- hopefully you wouldn't even want to try! But you can draw cross-origin images without tainting the canvas by satisfying CORS security restrictions.

The "usual" (and simplest) way of handling images so they don't taint the canvas:

Put your images in the same domain as the webpage. You can have several physical servers delivering content but the image domain must be the same as the html code (or the javascript code) that creates the canvas. CORS restrictions are satisfied and the canvas is not tainted.

Notes about CORS while you're developing on your own computer

Solution#1(!): You can install a web server on your dev computer and serve both the web page files (.html, .js, etc) and your image files (.png, .jpg, etc) from one domain.

The folders of your development computer are declared to be different domains. So drawing an image from a subdirectory on your local disk will violate CORS restrictions because different local folders are different domains.

Solution#2: While doing development, you can put both your webpage files and your image files on your desktop and the images will be declared to be in the same domain and your canvas will not be tainted.

Satisfying CORS restrictions when images are on different domains

Solution#3: You can use cross-domain images on canvas without tainting it. To do that, you must satisfy these requirements:

  • Clientside: The image object must have the crossOrigin attribute set to allow cross-origin content. This property can be set within the html element tag or within javascript. Enabling settings are "anonymous" and "use-credentials".

  • Serverside: The server must be configured to return header(s) indicating that the response contains authorized content.

More than 1 response header might be needed depending on configuration:

Access-Control-Allow-Origin will return either anonymous authorization (*) or will return specific authorization based on the request.

Access-Control-Allow-Credentials is required if authentication requires additional information (like cookies).

Access-Control-Expose-Headers gives the client access to additional response information.

Enabling cross-domain requests on the server can be complex, especially when serving content that is authorized based on client roles. For additional information about starting configuration, you can visit: http://enable-cors.org/index.html.

Using cross-domain image hosts that allow anonymous access to their images

Solution#4: Some public image hosts allow you to upload images which will be served to clients in a CORS compliant way. Several examples are: imgur and dropbox. Stackoverflow images are hosted on Imgur.

Here's an example of how to serve images on Dropbox.com in a CORS compliant way:

  1. Sign up for a Dropbox Account.
  2. You are given several default folders. Upload your images in the special "Public" folder. This is the folder that Dropbox gives CORS compliant anonymous access.
  3. Right-click on an image you want to serve and select "Copy public link". Your clipboard will have a link to your CORS compliant image.
  4. Load the image onto your page with the img tag or in javascript.

Here's example code to get a CORS compliant image object from Dropbox using javascript:

var img=new Image();
img.crossOrigin='anonymous';
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
img.onload=start;
function start(){
context.drawImage(img,0,0);
// The canvas is not tainted so
// the following both work without errors
var url=canvas.toDataURL();
var imageData=context.getImageData(0,0,100,100);
}

New(ish): Satisfy CORS by having the clientside user give consent

CORS security restrictions are meant to stop bad people from secretly taking your information while leaving you unaware.

Until recently, browsers relied on client-server configuration to satisfy security requirements. Recently, browsers have begun allowing cross-origin content if the user is affirmatively involved in deciding what content is being used.

Solution#5: Chrome and Firefox now allow the client-user to right click the canvas & save the canvas as an image. This is the manual equivalent of using canvas.toDataURL to create an image object and save that image object to the local drive. CORS is satisfied because the user decided if the canvas content was appropriate to save to their local drive and they affirmatively right-click to initiate the download process.

Solution#6: You can use an input element, type='file' to let the client-user select an image. The user can even select an internet URL (http://...). Again, CORS is satisfied because the user is involved in the selection process.

Here's example code showing how to listen for the user to select an image using an input:

// canvas varsvar canvas=document.createElement("canvas");var ctx=canvas.getContext("2d");
// define max resulting image width,height (after resizing)var maxW=100;var maxH=100;
// listen for user to select filesvar input = document.getElementById('input');input.addEventListener('change', handleFiles);
function handleFiles(e) { var img = new Image; img.onload = function(){ var iw=img.width; var ih=img.height; // scale down, if necessary if(iw>maxW || ih>maxH){ var scale=Math.min((maxW/iw),(maxH/ih)); iw*=scale; ih*=scale } // set canvas width/height to scaled size canvas.width=iw; canvas.height=ih; // draw+scale the img onto the canvas ctx.drawImage(img,0,0,iw,ih); // create a jpeg URL (with medium quality to save "weight") var jpg=canvas.toDataURL('image/jpeg',0.60); // In Demo: add the jpg to the window // In production, accumulate jpg's & send to server $('<img />',{src:jpg}).appendTo('body'); } // In Demo: Just process the first selected file // In production: process all selected files img.src = URL.createObjectURL(e.target.files[0]);}
body{ background-color: ivory; }#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><h4>You can even enter a web URI (http://...)</h4><input type="file" id="input"/><br>


Related Topics



Leave a reply



Submit