I'm trying to implement some JS library on Chrome extension that scans all images if contain nudity. Anyway, doing that by trying to read the context of canvas for each image, I'm having the exception below. This will happen on every page. I don't understand why I'm having this exception and how should I handle/avoid it.
Exception on script.js:33
Uncaught SecurityError: Failed to execute 'getImageData' on
'CanvasRenderingContext2D': The canvas has been tainted by cross-origin
script.js:
$(window).load(function() {
console.log('NudityBlocker -- Loaded');
$('img:visible').each(function() {
var uniqueId = guid();
var thisImage = $(this);
thisImage.css('visibility', 'hidden');
thisImage.attr('data-nudejs-id', uniqueId);
setTimeout(scan(thisImage), 0);
});
console.log('NudityBlocker -- Finished scanning');
});
function scan(image) {
// Create necessary elements
var nudeJsId = image.attr('data-nudejs-id');
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
// Draw image on canvas
canvas.width = image[0].width;
canvas.height = image[0].height;
ctx.drawImage(image[0], 0, 0);
// Get image date and create scanner worker
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
var myWorker = new Worker(nudeUrl);
var message = [imageData, canvas.width, canvas.height];
myWorker.postMessage(message);
myWorker.onmessage = function(event){
var imageObj = $('[data-nudejs-id=' + nudeJsId + ']');
if(event.data){
// It's nude
var width = imageObj.width();
var height = imageObj.height();
imageObj.attr('src', chrome.extension.getURL('assets/images/blocked.png')).width(width).height(height);
}
// Display images again either original or with blocked sign
imageObj.css('visibility', 'visible');
}
}
// Generate GUID's
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
background.js
function executeScripts(tabId) {
console.log('NudityBlocker -- ExecuteScripts()');
chrome.tabs.executeScript(tabId, {file: "assets/js/jquery.min.js"}, function() {
chrome.tabs.executeScript(tabId, {file: "assets/js/nudejs.min.js"});
chrome.tabs.executeScript(tabId, {file: "assets/js/script.js"});
});
}
var onComplete = function (details) {
executeScripts(details.tabId);
}
var onUpdate = function (tabId) {
executeScripts(tabId);
}
function updateIcons() {
console.log('NudityBlocker -- updateIcons()');
chrome.storage.sync.get(['nudityBlockerStatus'], function(items) {
status = items.nudityBlockerStatus;
console.log('NudityBlocker -- updateIcons() - Status: ' + status);
if(status === 'enabled') {
chrome.browserAction.setIcon({path: "assets/icon/icon48a.png"});
}
else if(status === 'disabled') {
chrome.browserAction.setIcon({path: "assets/icon/icon48d.png"});
}
});
}
function updateStatus(status) {
console.log('NudityBlocker -- UpdateStatus()');
console.log('NudityBlocker -- UpdateStatus() - Status: ' + status);
var result;
if (status === 'enabled') {
result = "disabled";
chrome.storage.sync.set({'nudityBlockerStatus' : result});
chrome.tabs.onUpdated.removeListener(onUpdate);
chrome.webNavigation.onCompleted.removeListener(onComplete);
}
else if (status === 'disabled') {
result = "enabled";
chrome.storage.sync.set({'nudityBlockerStatus' : result});
addListeners();
}
updateIcons();
return result;
}
function addListeners() {
console.log('NudityBlocker -- AddListeners()');
chrome.tabs.onUpdated.addListener(onUpdate);
chrome.webNavigation.onCompleted.addListener(onComplete);
}
function initialize() {
console.log('NudityBlocker -- Initialize()');
chrome.storage.sync.set({'nudityBlockerStatus' : 'enabled'});
console.log('NudityBlocker -- Initialize() - Status: ' + status);
updateIcons();
addListeners();
}
// Add event listeners
chrome.runtime.onInstalled.addListener(initialize());
P.s. The most similar issue to this that I found in StackOverflow is this below:
Canvas has been tainted by cross-origin data via local chrome:// extension URL
But this is not a duplicate, also I didn't fully understood the answer of it.