-2

Simple question, and I'm sure it's being asked a number of times already!

How can I prevent a link to my JS file being clicked on in my source code?

I'm creating an Angular JS SPA website and have resolve in action already, so it's virtually impossible to access links by appending the url as it will always bounce back to the home page, which is what I want.

However, I need to hide my src code and have numerous ways of doing this already but simply want to prevent the link in the source code from being 'clickable'.

I have managed to do it like this for my CSS (Google method), which is similar to what I want:

<script type="text/javascript" defer="defer">
    var cb = function() {
        var l = document.createElement('link'); l.rel = 'stylesheet';
        l.href = 'stylesheets/style.css';
        var h = document.getElementsByTagName('head')[0];
        h.parentNode.insertBefore(l, h);
    };
    var raf = requestAnimationFrame || mozRequestAnimationFrame ||
    webkitRequestAnimationFrame || msRequestAnimationFrame;
    if (raf) raf(cb);
    else window.addEventListener('load', cb);
</script>
Richard Ansell
  • 916
  • 1
  • 12
  • 28
  • 1
    That's beyond your power. If you serve the client your source code that contains the links, it's only in his discretion how to display that link and whether it is "clickable". Regardless how it's displayed, a link can always be followed. – Bergi Mar 10 '16 at 20:27
  • Please see my update above as it works for CSS, also I did try a similar method before the JS and it worked, but stopped working on page refresh.. – Richard Ansell Mar 10 '16 at 20:32
  • 1
    It doesn't matter, they can still see it if they inspect the live page. For the script or CSS to be used in the browser, the browser has to download it. If it's downloaded, then the user has it and can do whatever they want with it. The truth is if you have something in there you don't want the client to see, don't put it in client code. Put it in server-side code. – Nathan K Mar 10 '16 at 20:36
  • 1
    In your script above, I see: `l.href = 'stylesheets/style.css';`. How would stashing this in the script prevent me from finding it in the source code? – Scott Marcus Mar 10 '16 at 20:43
  • @ScottMarcus: op doesn't care about finding: `simply want to prevent the link in the source code from being 'clickable'.` – dandavis Mar 10 '16 at 20:49
  • 1
    @dandavis What's the difference? Clickable links in source is a feature of the browser. I could just copy/paste the URL all the same. – Nathan K Mar 10 '16 at 20:51
  • Just giving yourself a false sense of security doing any of this. Won't prevent those url's showing up in browser dev tools or other network tools like fiddler – charlietfl Mar 10 '16 at 20:55
  • @NathanK: i dunno, but OP wants what he wants... – dandavis Mar 10 '16 at 20:55
  • @dandavis That is true. But I think there's an important education component here depending on why they want this. If they need to hide business critical information, it needs to be clear that this won't help them. If they just want to stop lazy snoopers, then it might. But even that bar is very low. – Nathan K Mar 10 '16 at 21:00
  • @NathanK: well, it also hides the resource from "bots" that don't run JS, which might prevent automatic discovery and/or "drive bys"... – dandavis Mar 10 '16 at 21:05
  • 1
    There are duplicates of duplicates of this question and the answer hasn't changed in 8-years. [How can I obfuscate JavaScript?](http://stackoverflow.com/questions/194397/how-can-i-obfuscateprotect-javascript?lq=1) and [How do I hide javascript code in a webpage](http://stackoverflow.com/questions/6869312/how-do-i-hide-javascript-code-in-a-webpage) – Yogi Mar 10 '16 at 21:08
  • Thanks for all your help. Simply wanted just another method of making it more difficult for users to viewing my JS as I don't have means of using a server in this scenario. The only option I can think of is using an obfuscator and making Firebase calls to context-sensitive data that does require authorization regardless. – Richard Ansell Mar 10 '16 at 21:08

4 Answers4

7

Short answer: you can't. HTML, CSS and JavaScript are called client-side code for a reason. You can NEVER hide the resulting code from the HTTP Request. You can certainly obfuscate it, but never hide it.

After some discussion in the comments below, I feel it's important to follow up by saying that while your question asks about preventing users from seeing your links and clicking on them in the source code, it really "feels" like your question is really "Can I prevent users from seeing my links in my source code?" I may be wrong, but from our discussions, that's what it seems like. And, if that is really your question, then it's a question about security and the clear answer on that is that there is never a way to secure your client-side code from prying eyes.

Many sites obfuscate their code (change variable and function names to seemingly meaningless names, encode URLs, etc), but in the end, if someone wants to inspect your code and tear it apart, they can.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Please see my update above as it works for CSS, also I did try a similar method before the JS and it worked, but stopped working on page refresh.. – Richard Ansell Mar 10 '16 at 20:32
  • If I were to open that page up and turn on my developer tools and take a look at the parsed DOM, I would see your fully parsed script tag and its src. You cannot prevent clients from seeing the code sent to them or created by them. – Scott Marcus Mar 10 '16 at 20:35
  • @RichardAnsell Don't look at the "source" tab of the developer tools, look at the "elements" tab. – Scott Marcus Mar 10 '16 at 20:41
  • I understand where you're coming from, but I can't open the CSS file in this scenario as due to the security protocols I've got in my app that prevents users from accessing pages that are not allowed. If I could do something similar to what I've described, that would be ideal. – Richard Ansell Mar 10 '16 at 20:45
  • @RichardAnsell: If users are not allowed to access the script/style file, they can't use. If they need to use it, they will be able to view it. – Bergi Mar 10 '16 at 20:48
  • @RichardAnsell As Bergi says, this doesn't make any sense. If the folder is blocked from access, then your page won't be able to get to the file(s). – Scott Marcus Mar 10 '16 at 20:49
  • @RichardAnsell If the browser can download it to use, then they already have it. – Nathan K Mar 10 '16 at 20:50
  • Final idea, is there a way to store the link in another JS file and call upon the other file and the link into the index.html page then? – Richard Ansell Mar 10 '16 at 20:51
  • @RichardAnsell Sure, but I will be able to see that JS file and open it up and see the link there. You'll NEVER be able to hide the path from the user if the reference is in client side code. – Scott Marcus Mar 10 '16 at 20:52
  • @RichardAnsell It doesn't matter. Eventually the browser has to download that file to use it, and when that happens the client has complete access to the whole thing. It doesn't matter if you have a chain of a 1000 files, eventually the browser will download the last one and they'll have it. This is how The Internet works. – Nathan K Mar 10 '16 at 20:53
  • Seems like your suggested options are the only options available @Nathan K, thanks again – Richard Ansell Mar 10 '16 at 20:55
2

You can't.

If the code is run in the browser, the user has complete access to it. In your CSS example, I could simply inspect the DOM and see the <link> element that it added and easily find the source. It's the same effort as looking at the source. Even if you some how hid it (you can try, but it won't work), I could inspect the actual HTTP requests my browser is making and read the script in the body of the request itself. You can't hide it.

So what can you do?

Obsfucate It

This usually involves running your script through a parser that makes hard for a human to read. This doesn't actually hide anything, it just makes it more difficult to figure out exactly what it does. The client still has full access to it. This is not security and anyone who really wants your code has it.

Put It On The Server

If you absolutely do not want the client to see your JavaScript, don't send it to the client. Implement the parts you want to hide on the server and have the client only request the information it absolutely needs (which the client will be able to see).

This won't apply to CSS as the browser needs the CSS to actually render the page, in which case the client can see all your CSS whether it's there on load of the page or added to the DOM later.

Community
  • 1
  • 1
Nathan K
  • 226
  • 1
  • 5
  • Would be great if I could use a server, except I'm using Firebase's static hosting for my app so can't go down this route unfortunately. – Richard Ansell Mar 10 '16 at 20:48
  • @RichardAnsell Then there isn't anything you can do except obsfucate it. But don't rely on that for security, because it is not security. – Nathan K Mar 10 '16 at 20:49
0

you can simply modify your CSS injector to add JS instead:

<script>
    var cb = function() {
        var l = document.createElement('script');
        l.src= 'script.js';
        var h = document.getElementsByTagName('head')[0];
        h.parentNode.insertBefore(l, h);
    };
    var raf = requestAnimationFrame || mozRequestAnimationFrame ||
    webkitRequestAnimationFrame || msRequestAnimationFrame;
    if (raf) raf(cb);
    else window.addEventListener('load', cb);
</script>

this will add 'script.js' to the document, and the url of the external script will not be clickable from "view-source".

It will NOT stop any dev from finding your scripts.

dandavis
  • 16,370
  • 5
  • 40
  • 36
0

Unpopular opinion guy here, but you can use jQuery's getScript and it will eval() the code into your page (with no link). Granted, the link you're GETTING will be in the getScript call unless you do something like get the URL from an API endpoint. . .

cchambers
  • 76
  • 5
  • good point. you could import a whole chunk of HTML+CSS using `$.fn.load()` – dandavis Mar 10 '16 at 20:55
  • 1
    This is just another layer of obsfucation. Anyone who wants the code will be able to get it. But then again it doesn't matter, because once they browser has it they only have to use dev tools to view it. – Nathan K Mar 10 '16 at 20:56
  • This doesn't help you. I can see the XmlHttpRequest response in the developer tools. I can see the parsed version of the DOM in the Elements tab. – Scott Marcus Mar 10 '16 at 20:58
  • I understand where you are all coming from, but the question was preventing a link to the file appearing in the source code, which this does. – cchambers Mar 10 '16 at 21:04