Clone Unclonable Images with Javascript

Clone Unclonable Images with Javascript

There are some images that developers don't want you to clone, for multiple reasons.

I will give a concrete example, the CAPTCHA images. One of the reasons they don't want you to clone/duplicate them is because of the CAPTCHA solvers. If you send those pictures to them, they will solve them and return you the result.

How to identify them?

They don't have an extension on them, like jpeg, png, etc... They are generated from the server side and will serve them only once. Let me give you an example.

<img src="/Generated/001244"></img>

once rendered, that's it. If you try and enter that URL again into the browser, most likely you would get something like this:

Forbidden image Picture 1: This is how might look when you want to access that image for the second time.

Can I clone it with another img tag?

You can go ahead and try this:

<img id="CaptchaImage" src="/Generated/001244"></img>
<img src="/Generated/001244"></img>

might result that second image in Picture 1. And still, if it does that, what you really want is to convert that image into base64, since we have no use of that src link.

By converting it to base64, we are no longer depended on the server's response, which is what we actually want to achieve. That way, we can save picture or decode it on the page (duplicate it).

Solution? Draw picture within the canvas.

We should draw that image within the canvas. That way, we can convert the canvas in the base64 and capture the image that way.

var x = document.createElement("CANVAS");
x.setAttribute('id', 'canvass')
document.body.append(x)
var c = document.getElementById("canvass");
var ctx = c.getContext("2d");
var img = document.getElementById("CaptchaImage");
ctx.canvas.height = // img.height
ctx.canvas.width = // img.width
ctx.drawImage(img, 0, 0);

This code appends the CANVAS into the page, then we draw the image within the context of the canvas. And once that is done, we have a cloned/duplicated image on the webpage.

Javascript and it's not so obvious Prototype behaviour.

Finishing touches

Now is the time to get that canvas and convert it into base64. You can easily do this by calling the method:

var jpegUrl = c.toDataURL("image/jpeg");

which will result in a long string:

"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2w...

and that's it. You can send that as a link to open in a new browser which is not recommended because the string can get quite long, or you can create a Blob and download it on your computer.

Be sure to enter your email in the box below this post to get the bonus content of each post I cover. Zero spam, just additional content.