For Navigation: Cursor =====>
You cannot protect your code from being downloaded. But there is quite a number of ways to prevent a
Compacting
Javascript, like just about all modern programming languages, is "free format". That is, at any place among the (reserved) keywords, the (user-defined) identifiers and the (numeric or string) constants there can be a whitespace interspersed - whatever you think will make your source code easier to read.
Or, looking at it the other way round, nearly all "whitespace" can be removed, if you want to camouflage your source code to humans. Still it will be perfectly readable to the browser. There are just a few exceptions to "free format" (move cursor here)
Look for yourself. Let's assume, we had a simple function like the following:
function Respond(i)
{
switch(i)
{ case 1: alert('Button "1" clicked'); break;
case 2: alert('Button "2" clicked'); break;
case 3: alert('Button "3" clicked'); break;
}
}
As well, you could code that function as follows. (Note)
function Respond(i){switch(i){case 1:alert('Button "1" clicked');break;case 2:
alert('Button "2" clicked');break;case 3:alert('Button "3" clicked');break;}}
Still the browser will interpret it just like the original one above. Try it - click on any of the following buttons:
Randomizing
To the browser, your user-defined identifiers are just a plain character sequence, formed in compliance with some syntactic rules. (Move cursor here, if you want to know the syntactic rules of identifiers in Javascript.)
Again, let's look at it the other way round: If you replace an identifier by any random character sequence, it's just as well to the browser. What counts, is only that every occurrence of an identifier is replaced by the identical char sequence.
So, you could reformat the above code by replacing the function name (Respond") and the one parameter "i" by random char sequences, as in the following coding scheme:
function sCwGe2Qq(efN9brFo){switch(efN9brFo){case 1:alert(
'Button "1" clicked');break;case 2:alert('Button "2" clicked');
break;case 3:alert('Button "3" clicked');break;}}
Still the browser will interpret it just like the preceding one. Just be sure that this function must be called by its random name now, e.g. onclick="sCwGe2Qq(1)" Try it - click on any of the following buttons:
Code Manipulations
The next step in camouflaging your source code would be, to replace parts of your code by another code that could be aDetails to both you will find in the following sub-sections.
Code Manipulations - Homologies
Remember the original sample code. (When you click this link, it will be displayed in an extra window. Thus you can lay it aside in the task bar, so you have it right at hand when you need it.) An obvious homology would be to replace the switch-statement by an equivalent statement, occupying just one line of code. Thus you would arrive at the following coding scheme, displayed here in plain text to show the equivalence:
function Respond(i)
{ alert('Button "' + i + '" clicked'); }
To make it a bit more confusing to a potential code pirate, you could factor out the parts of the string:
function Respond(i)
{ var part1='Button', part2='clicked';
alert(part1 + ' "' + i + '" ' + part2);
}
When you randomize the function name and the identifiers, you get a code that is fairly confusing already, for example (but remember: Line breaks are ...):
function M_8B32$(uMXa8YpHb6kq){var R3cl$YEuUOsu='Button',
HWo6_a98OJkR='clicked';alert(R3cl$YEuUOsu+' "'+
uMXa8YpHb6kq+'" '+HWo6_a98OJkR);}
However, the browser will still interpret it just like the original code. Just be sure that this function must be called by its random name now, i.e. onclick="M_8B32$(1)" Try it - click on any of the following buttons:
A general problem with homologies is that there is no save way to translate the original code. It will always take some creativity to find suitable equivalents, and some careful coding to implement it correctly.
Code Manipulations - Factoring out
A simple yet very effective method is factoring out. That is
Let's assume, you want to camouflage the following code:
So, we introduce three new variables, e.g.:
It's a good idea to avoid obvious splitting, such as var part1='IT', part2='special', part3=".org';
Next, we're going to randomize the variable names:
Now let's combine these variables:
Finally, you should spread the three variable declarations all over the document. Just don't forget that each one must be in brackets <SCRIPT> </SCRIPT> The first declaration could be near the beginning:
The second declaration could be somewhere in the middle of the document:
The last variable should be declared somewhere near the end of document (could even be past the initial place):
You see, the idea is simply to "drive him crazy", the potential code pirate. When starting at the initial place, it would be very hard to find all the constituent parts and their values.
Code Manipulations - Fake Code
You might feel that such a simple code would not be much of a deterrent to a potential code pirate? Well, you could easily blow it up to any complexity. Just add some "fake code". "Fake code", that's some kind of window-dressing. To make a code sequence look great, while in effect it's only a few lines of code. The parts surrounding or placed between the effective lines are blocked out by any condition that will never become true. Thus the fake code is never activated. So the fake code can be anything, it should only be syntactically correct. In practice you will simply copy any code from a different function. Just make sure that all its identifiers are declared, though they will never be used. The coding scheme is as follows:
function YourFunction(param1,param2, /*...*/ )
{
var id1, id2, ..., // identifiers of the effective code
id_a, id_b, ... // identifiers of the fake code
if (cond1) // 'cond1' will never come true
{ fake_code1 }
effective_code1
if (cond2) // 'cond2' will never come true
{ fake_code1 }
:
}
When you compact the total code and randomize its function names and identifiers, it will look just as if it was of a piece. A potential code pirate will not be able to determine which code parts are fake code and which parts are effective code, i.e. highly sensitive to tinker with. Not without careful thinking, that is.
For example, look at the following coding scheme (which, in effect, is nothing more than the original sample code). Can you see at a glance what are the effective parts of code; what is fake code, inserted just for confusion? (Remember: Line breaks are ...)
function hzXLTvcl(n){var woE2NuXI='Button',GeFDzYPe,QigiXyJu=0;
if(QigiXyJu)for(GeFDzYPe=0;QigiXyJu=QigiXyJu.children.item
(GeFDzYPe);GeFDzYPe++){if(QigiXyJu.tagName!='DIV')continue;if
(QigiXyJu.className!='')continue;QigiXyJu.style.display='none';}
var Bfsy$SmI='clicked',nb3cXPFg=document.all.tags('OBJECT');for
(GeFDzYPe=0;GeFDzYPe<nb3cXPFg.length;GeFDzYPe++){if(
nb3cXPFg(GeFDzYPe)==div)continue;if(nb3cXPFg(GeFDzYPe)==
div.parent)continue;if(nb3cXPFg(GeFDzYPe).className=='')
nb3cXPFg(GeFDzYPe).style.display='none';}var RiIfTHTd,
r1eOOc8W=woE2NuXI+' "'+n+'" '+Bfsy$SmI,PHv32Ulp;if(RiIfTHTd)
{OLsUL8el(RiIfTHTd);if(PHv32Ulp)PHv32Ulp.close();PHv32Ulp=0;
}alert(r1eOOc8W);var Ln0XxJCu,m$gN3K4w,n6st5LOM;
if(Ln0XxJCu){m$gN3K4w=event.clientX+document.body.scrollLeft;
n6st5LOM=event.clientY+document.body.scrollTop;}}
Yet, the browser will still interpret it just like the original code. Just be sure that this function must be called by its random name now, i.e. onclick="HxzwvlifVzyg(1)" Try it - click on any of the following buttons. They will call a code equivalent to the coding scheme above:
Masking
A widespread strategy of code piracy is to look for conspicuous character sequences - like keywords or plain-text strings - and to trace back the code from them.
So, if we want to thwart this strategy, we should try to transform the intelligible character sequences such that they turn out like being "meaningless" streams of characters, similar to the random char sequences replacing the identifiers.
Masking - Keywords
Most keywords cannot be transformed individually but only in compound of a statement. That statement can be made to an extra function, which offers some advantages for code defacing:
For example, let's take the sole statement of our sample function. In plain text it is
alert('Button "' + i + '" clicked');
This statement could be replaced by an extra function:
Msg('Button "' + i + '" clicked');
The declaration of the extra function Msg would simply be:
function Msg(msg) { alert(msg); }
Move that declaration out to any separate <SCRIPT> </SCRIPT> block (far away from the main code), and randomize the function name,
Finally, don't forget to replace the name of the function called in the main code by the random name:
Masking - Global Variables
If you feel, the function argument of calling the extra function in the preceding sub-section would be too revealing, then you can introduce a global variable initialized to that argument.
In an HTML-document, a global variable can be declared at any place within a <SCRIPT> </SCRIPT> block. It can be accessed from every other function in the same HTML-document, even if that function is declared within a different <SCRIPT> </SCRIPT> block.
In our sample code, this could be used as follows:
Finally randomize the variables, in the declaration as well as the call:
Another trick you can play with global variables is using them for
passing information to/from a function, instead of passing it
Masking - Strings
If you are still not satisfied, on top of all that you could even mask the string constants. By any binary operation you could transform each character.
A useful way to do that is the XOR-operation (XOR = exclusive or). That's because XOR is an "auto-inverse" operation: xor-ing a character with any key, and xor-ing the result with the same key, yields the original character. So, for masking a string and for
That xor-ing function could be quite simple:
function PZkXZNOa(str,keychar) // function 'Mask()', randomized
{
var st='', k=keychar.charCodeAt(0);
for (i=0; i<str.length; i++)
st += String.fromCharCode(str.charCodeAt(i) ^ k);
return st;
}
Then you could replace the strings in the declaration of the global variables by:
(might well be that some of the xor-ed characters
cannot be displayed correctly in your browser)
Internally those confusing strings will be transformed back to the original strings. This is equivalent to having declared the global variables as
Masking - Custom Attribute
Another way for masking a constant (number or string) is:
For example, in the second META-tag of this document there is a custom attribute:
Let me invite you to right-click anywhere on the screen
and to click "View Source" in the context-menu!
When you click the following button, the value of abc is retrieved:
The HTML-code to do that is simply
where the function ShowCustAttr() is just two lines of code:
function ShowCustAttr()
{ var obj=document.all.tags('META').item(1);
alert('xyz= ' + obj.getAttribute('xyz',1)); }
The name of a custom attribute can be any char sequence complying to the same rules as an identifier.
Ok, you have a bit more code. (But after all - isn't that just what you need for confusing a potential code pirate?)
On the other hand, with a custom attribute you have several liberties:
Locking to Environment
You want your functions to work on your website only, so no software pirate can make any use of them. To ensure that, you have several possibilities:All of these methods of course will work only if you can cleverly conceal the setting and checking of key values or asking for document.domain. Therefore, they will be useful only if combined with some of the other methods described here, in particular Compacting and Randomizing.
Details to these methods will be given in the following sub-sections.
With some fantasy you might well come up with some ways of elegantly concealing these statements, that not even I myself would have ever dreamed of!
Lock to Document
The main idea here is to hide one or more keys somewhere in the document, to compare it/them, and to abort a function if it/they is/are different.
To declare a key, you need to intersperse the following code at any place in your document. (It can be between </TITLE> and </HEAD> tag, or at the document's end between </BODY> and </HTML>, or even right in the middle of the text - it will not be displayed (Remember: Though displayed in plain text here, ...):
At the logical begin of each function you want to lock to document, check the key value(s) and abort, if not correct (Remember: Though displayed in plain text here, ...):
function LockedFunction(...)
{
:
... fake code ...
:
if (key != '
') return;
:
... effective code ...
:
}
' ' is any random character sequence - evidently the same as key was initialized with at declaration.
Lock to Domain
For that you need to take even less effort. It's enough to check at the logical begin of each function you want to lock to your domain:
function LockedFunction(...)
{
:
... fake code ...
:
if (document.domain != '
') return;
:
... effective code ...
:
}
' ' is the domain your website is registered to, i.e. www. .com or similar. For practical use it will be a good idea to mask this string (see sub-section Masking - Strings). Or it will be too easy for a savvy code pirate to find the lock and to eliminate it.
The attribute document.domain is set by your host's server before your document is sent to the visitor's computer. When a code pirate tries to run you function, this attribute will remain empty, so you can easily detect the piracy.
Style Manipulations
Another widespread strategy to trace back the code is starting out from a significant style. In inline-style notation that's another explicit string, so it is easy to find.
To prevent that, you have two possibilities:
By a CLASS=" "-attribute you can avoid declaring an explicit style string. Leave it to the browser to assign the style.
See next sub-section.
At coding time, do not assign a style at all. Just declare the object to be styled as being CLASS=" " and declare that class name in a style sheet (local or global). Not before runtime, set the object's class name and leave it to the browser to assign the style.
See sub-section after the next.
Style Manipulations - Style Sheet
You can avoid giving explicit style declarations. Instead of an attribute STYLE=" " you declare the object to be styled as CLASS="xyz" and, in turn, declare a style sheet:
Style sheets are most useful if you have a number of objects of the same style. Then you need to declare the style string only once, all the objects are simply declared as being CLASS=" " So, that you can use them also for preventing code piracy is just a pleasant side effect. If you have many objects in separate documents, all with the same styles, you might consider to use a global style sheet:
Style Manipulations - Dynamic Styling
The main idea of Dynamic Styling is, at coding time not to assign a style at all. Just declare the object to be styled with an attribute CLASS=" " and declare that class name in a style sheet (local or global).
At runtime, in any function in Javascript (or any other scripting language you prefer), or right within the event declaration, assign a class name to the object:
Assignment of the individual style features is done by the browser.
For example, the following seemingly "button" is just a DIV with a class name up. When clicked, the object's class name is changed to down. When released, it is changed to up again:
Flexible Includes
You can even have objects with no (static) code at all. All that is there, is a code line <SCRIPT> </SCRIPT> with a formal description of what code is to be generated at runtime.
When loading your document, the browser interprets this description and generates the respective code on its own.
So, when no (static) code at all - there's nothing a code pirate could pilfer. And if the function generating the code at runtime is protected as outlined in the previous sections (compactified, randomized, locked in environment), a potential code pirate will have hardly any chance.
Details about Flexible Includes you can find in article Flexible Includes - Common Code, but Individually Adaptable
Flexible Includes can also use Dynamic Styling. For example, take the following row of "buttons":
In static code, it is nothing but a code line as the following:
In it a function Buttons is called that does the code generation at runtime:
function Buttons(/*
*/)
{
var Up="'"+'up'+"'", Down="'"+'down'+"'", label, i;
for (i=0; label = Buttons.arguments[i]; i++)
{
document.write ('<DIV CLASS="up" ');
:
document.write ('onmousedown="this.className=' + Down + '" ');
document.write ('onmouseup="this.className=' + Up + '"'>');
document.write (label + '</DIV>');
}
}
The class names up and down are the same as declared in the preceding sub-section.
Challenge
Now, with all these protections built in, let me challenge you: Can you download the following function and make it work on your own computer - without disturbing its full functionality, of course? With such a simple function, I cannot claim definitively that you cannot do it, after all. (Well, in the end I myself had problems to verify the code ) Try it! Download the last function in the source code (called "Respond5"), and find a way to get around the locks built in. Believe me, there are no tricks built in except those described in this article. And even if you can crack it - ask yourself: How much time did it take to download it and make it work? If you were able to do that, you must be quite fit in programming. So, wouldn't it have been much more sensible to program such a simple function yourself? After downloading, can you make it work like the function behind the following buttons?
If you manage to make it work just like the original function above, your name and address will be published in the following table. Please email me at gg@ITspecial.org. Don't forget to include your name + address, and attach what you made out of my code! (And, for my personal curiosity, tell me please: How did you do that?)
| Name | Address | Date |
|---|---|---|