Forum Moderators: open
I was wondering if there is a way to protect a javascript code?
I took a long time to code some nice tools for my visitors but im afraid they will be copied easily without even asking for permission.
Not that i dont want to share, just that i d like to know about it kinda respect point of view :)
Thanks
To all those people earlier in the thread that said this wasn't possible - can you please give it a go? I'm genuinely curious as to how effective this approach is.
I'll offer a free mars bar to the first person to get it :)
The main page, save as tst_188.htm:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="tst_188.js"></script>
</head>
<body>
<form action="">
<input id="inOne" type="text" value="1" />
</form>
<a href="#" onclick="testOne();return false;">test the test</a><br /><br /><br />
<iframe id="ifrOne" src="tst_188a.htm" style="visibility:hidden;"></iframe>
</body>
</html>
The page for the iframe, to be generated by PHP in the final rendition, save as tst_188a.htm (obviously, make sure the ternary pastes as one line):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Script setup file</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="tst_188a.js"></script>
<script type="text/javascript">
var nav_agt=navigator.userAgent;
nav_agt.indexOf("MSIE")!=-1 && nav_agt.indexOf("Opera")==-1? parent.document.getElementsByTagName("script")[0].src="tst_188a.js" : parent.testOne=testOne;
window.location.href="tst_188b.htm";
</script>
</head>
<body>
<p>
This is the page to serve from a server-side script in the final product.
</p>
</body>
</html>
The first .js file, save as tst_188.js:
function testOne(){
alert("first .js file");
}
The second .js file, save as tst_188a.js:
function testOne(){
var x=parent.document.getElementById("inOne").value;
alert("From the input: "+x+"\r\nThis came from the iframe")
}
Finally, the dummy replacement page, save as tst_188b.htm:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>
<p>
This is the dummy file.
</p>
</body>
</html>
In my tests on Win XP with IE6, Moz 1.7, & Opera 7, this approach appears to defeat the page saving method of script capture. One minor problem as written is that Moz, on anything but a hard reload, will lose its reference to the second function. Obviously, using onload to trigger loading the iframe should fix that.
Do any of those 15 people have any comment to make on it? I got the impression lots of people claimed that any attempt to hide javascript was easily overridden, and a number of other people expressing a desire to find a way to do it. But neither of these groups have anything to say about a technique that might possibly allow this?
I could just post how it is done, but that would rather ruin the opportunity to see if someone can circumvent it. After all, the test isn't to see if you can find the source after being told how it is hidden, the test is to get the source knowing nothing as this is what would happen 'in the real world'.
I don't expect the nay-sayers will be quick to congratulate you. Also, this thread is getting a bit long in the tooth. If you'd like more action on your idea you might start a new post with something like "JavaScript secrets concealed/revealed -"
I'm not sure the moderators will allow your link to fly in a thinner context; you might find it necessary to reveal your tricks and simply invite comment.
However, I suspect that the problem would boil down to finding the right browser - one that doesn't obey all the rules properly. Perhaps an early version of IE 4 for instance or an old copy of Opera or Netscape. If the browser can read the script then it is readable. Any browser that that performs a Save Complete operation may potentially work - indeed it absolutely will work if it simply saves the data it has stored in memory (with necesary changes to links, etc.) rather than going looking for the pages, etc. again.
Kaled.
However, I suspect that the problem would boil down to finding the right browser - one that doesn't obey all the rules properly. Perhaps an early version of IE 4 for instance or an old copy of Opera or Netscape.
I think you are definitely on to something there. Opera in particular seems to treat certain instructions in a very strange way that might allow you 'in'.
If the browser can read the script then it is readable.
That has never been in dispute
Any browser that that performs a Save Complete operation may potentially work - indeed it absolutely will work if it simply saves the data it has stored in memory (with necesary changes to links, etc.) rather than going looking for the pages, etc. again.
I have tried this in both Firefox and IE and on both occasions it failed to display the executed code.
The first file, tst_188.htm:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="tst_188.js"></script>
</head>
<body onload="document.getElementById('ifrOne').src='tst_188a.htm';">
<form action="">
<input id="inOne" type="text" value="1" />
</form>
<a href="#" onclick="testOne();return false;">test the test</a><br /><br /><br />
<iframe id="ifrOne" src="" style="visibility:hidden;"></iframe>
</body>
</html>
The second file, for the iframe, tst_188a.htm (as before, make sure the line with the ternary operator pastes as one line, here word-wrap breaks it in two or three):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Script setup file</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="tst_188a.js"></script>
<script type="text/javascript">
var nav_agt=navigator.userAgent;
nav_agt.indexOf("MSIE")!=-1 && nav_agt.indexOf("Opera")==-1? parent.document.getElementsByTagName("script")[0].src="tst_188a.js" : parent.testOne=testOne;
window.location.href="tst_188b.htm";
</script>
<meta http-equiv="Refresh" content="1; URL=tst_188b.htm" />
</head>
<body onload="window.location.replace('tst_188b.htm');">
<p>
This page will self-destruct in 1 second (or less).
</p>
</body>
</html>
The first .js file, tst_188.js:
function testOne(){
alert("first .js file");
}
The second .js file, tst_188a.js:
// this is the obscured code
function testOne(){
var x=top.document.getElementById("inOne").value;
alert("From the input: "+x+"\r\nThis came from the iframe")
}
Finally, the dummy file, tst_188b.htm:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>
<p>
This is the dummy file.
</p>
</body>
</html>
// the hidden word is mushroom ;)
From when I actually sat down to crack the page it took about 45 minutes.
The final script used <30 lines of PHP (no browser required).
For Stark
// the hidden word is mushroom ;)
ahh, very nice - I owe you a mars bar! :)
Now, for the next challenge.... how to improve it?
Did you parse the key.js code in PHP? It was a little simplistic so I imagine that would not be hugely tricky.... if so, would obfuscating that particular code make the challenge significantly harder?