It can take a lot of time and effort to create unique and interesting web sites. Sadly, some people are more than happy to just copy your hard work, make some adjustments, and claim it as their own. Technically there is nothing you can do to stop them, but I wanted to make it a lot harder, and to hopefully discourage them. To do this I needed to put myself into their low life mindset and think like a scumbag, and try to come up with something that they couldn't easily circumvent.
Let's start by thinking about what they would do. These are the steps I would take to clone someone else's web site.
I cannot stop someone from crawling my web sites. I cannot stop them from changing the HTML and CSS. I cannot stop them from doing anything really. So what can I do? The only difference between my web site and their adjusted clone is the domain name. So maybe I could add some checks inside the JavaScript code to make sure it only runs on my domain.
When the page is loaded, the code checks the domain, and if it is not my site address, then nuke the client. This is my first attempt.
This works a treat. It checks the hostname of the location, which is the domain name of the site, compares it to my domain name ("coderundebug.com"), and if it is not the same then it removes all the heads and body HTML. This removes the whole site from the client's browser if they are viewing it from the cloned site.
The intrepid cloner will not be deterred so easily however. They will see that something odd is happening and will do a little digging. After some research they will look for the "coderundebug.com" text within the JavaScript code and replace it with their own domain name. Problem solved.
So what can I do about this? I cannot hard code the domain name in the source code otherwise it would be easy to find and change. The name of the domain cannot exist anywhere else, so the next best thing I can do is to hide it somehow. A simple method to hide some text is to use ASCII character codes instead. Here is my next attempt.
The list of hidden domain ASCII code values are converted into characters, using the fromCharCode function. I then use this variable when checking the hostname.
As I lower my ethical morals and think about how to circumvent this, I come up with the idea of searching for the hidden array of ASCII code values instead of the text. I know this clone check is being used, I have read the blog about it, so all I need to do is convert the domain name I stole it from and convert it into the array, and just look for that. Easy peasy.
So how do I overcome this? What I think is needed is to somehow make the code different, so that the domain name cannot be recreated and searched for. I can add some random "alpha" parts to the domain encoding. Below is another attempt.
I have created a decode function that converts the encoded ASCII array into a string.
It uses an alpha variable that can be 3, for where the index is odd, and 7, for when it is even.
These alpha numbers need to be added into the array of ASCII codes, so that when decoded, the output will be correct.
These two alpha values (3 and 7) can be created randomly when the clone code is created.
This way, the array can not be recreated from the domain name only, and therefore cannot be searched for.
Sadly I don't think this will prevent our worthless copycat.
With a bit more know-how and determination, they will just search for the document.head and document.body keywords and remove them.
In fact, the hostname is also something they could look for.
These keywords are probably not used all that often and searching for them will be quick and simple.
Is it possible to somehow not use them or hide them?
You can access an object's property using a string variable with the name of the property inside. The following example shows how this can be done.
Now, if only we could hide the names of the properties we want to use, we could stop them being searched for. My next attempt will hide a number of extra strings and use them to access properties (I am not showing all the code from now on).
I now decode the properties I want to use. The variables will be minified so their names do not matter at this point. Things are looking good.
A scuzz bucket low life will still not be beaten at this point.
They will just search for the keyword window and see if there are any [variable] text parts coming after it.
Using square brackets next to another set of square brackets is rare and they could just search for two end to end brackets ][.
How can this be prevented? Instead of accessing the properties in this way, I could create a function that does it for me.
I have added the getProperty function that takes an object and the name of the property I want to return.
This way I am calling the function a number of times to get the window.location.hostname property.
I am also using a variable w to hold the window object.
This should stop them for sure.
Normal people with a conscience would have given up by now, but for those destined for more eternal judgement, this will not stop them.
They will just look for the keyword fromCharCode, which generally isn't something most people use in their code base,
and as a result, will find the cloning check function.
I need to hide this function name too, but I cannot do it in the same way, I cannot use the fromCharCode function to get the “fromCharCode” text.
That's like asking who read the book “Catch 22” first, the chicken or the egg?
One method is to create a random string of characters that contains the characters to the text I want, all mixed up in different locations, and then create an array of the locations for each of the characters we want to put together. Here is an example of what I have in mind.
The fromCharCodeText variable is built using the random string rs and the list of random string numbers (or indexes within the random string).
I just grab the characters from the random string, one by one, to make the "fromCharCode" text.
This is then used with the s (set to the String object) variable to run the method required.
This is getting better.
I am still thinking like a cartoon villain and wanting to track down this problem code.
I know what I can do.
I will search for the keyword window and String (because it is used with fromCharCode).
That "String" object is never used much and it cannot be hidden like all those properties and functions.
I have to use the keyword "String", so that I can run the static function fromCharCode.
I cannot use an object by its text name.
I cannot do something like "String".fromCharCode(12).
I have no choice but to use the String object.
The same is true for the window keyword.
If I cannot hide them, maybe I could over complicate things, hide the real String object in a group of multiple String objects.
This nightmare is basically rubbish, but hidden inside is the real object we want to use. Trying to trace your way through this will give you a headache. This would all need to be created randomly too and could even be larger than the example shown.
The final code needs to create random parts so that it looks different on each site it is used on. To do this I will need to create a function that takes everything I have made so far, adds a number of random parts, to process a final, unique, difficult to find, site clone check code.
While thinking like a treacherous fraud, I have come up with a cruel idea to torment those trying to duplicate my site. While copying and changing the site, everything will work nicely on their own machine, because the host name is either "localhost" or "127.0.0.1", but only when the site is deployed will it end up being nuked. It works on their computer, but not on the web, why is this, what's gone wrong? I hope they spend hours wasting their time trying to figure it out.
I have also added in some extra rubbish code that does nothing. Loads of red herrings leading them down blind alleys and false hope, a maze of pointless mysteries and frustration.
You can use the tool below to create the site clone check code for your site. Enter the domain name of the site, select whether to minify the code, and press the "Create Code" button. Pressing the "Copy" button will copy the code shown on to the clipboard.
The best place to put the code is somewhere in the middle of a JavaScript file that is always used on most pages. You can also create a fake web component that does nothing but runs the code. Below is an example.
You will need to make sure to load the script in and include the <group-list></group-list> HTML tag.
How do you test that it is working? You could clone the whole site and deploy it to another domain, but that is too much work. Instead, you could create a local DNS record that points a fake domain name to the "127.0.0.1" IP address. This is what I do on my Windows 11 PC.
In your browser, go to the "http://testlocalhost.com" address (adding any ":8080" port numbers you may be using), and it should start getting files from the "127.0.0.1" IP address (your local machine). It will detect the host name is not valid and nuke the site. Be careful though, you may need to manually enter the starting "HTTP://"" part, because you do not want it to automatically start with "HTTPS://".