Javascript 如何保护javascript文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4766834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:59:05  来源:igfitidea点击:

How do I protect javascript files?

javascriptsource-code-protection

提问by Jmlevick

I know it's impossible to hide source code but, for example, if I have to link a JavaScript file from my CDN to a web page and I don't want the people to know the location and/or content of this script, is this possible?

我知道隐藏源代码是不可能的,但是,例如,如果我必须将一个 JavaScript 文件从我的 CDN 链接到一个网页,并且我不希望人们知道这个脚本的位置和/或内容,这是可能的?

For example, to link a script from a website, we use:

例如,要从网站链接脚本,我们使用:

<script type="text/javascript" src="http://somedomain.com/scriptxyz.js">
</script>

Now, is possible to hide from the user where the script comes from, or hide the script content and still use it on a web page?

现在,是否可以对用户隐藏脚本的来源,或者隐藏脚本内容并仍然在网页上使用它?

For example, by saving it in my private CDN that needs password to access files, would that work? If not, what would work to get what I want?

例如,将它保存在我需要密码才能访问文件的私人 CDN 中,这样可行吗?如果没有,有什么办法可以得到我想要的东西?

回答by gion_13

Good question with a simple answer: you can't!

好问题,答案很简单:你不能

Javascript is a client-side programming language, therefore it works on the client's machine, so you can't actually hide anything from the client.
Obfuscating your code is a good solution, but it's not enough, because, although it is hard, someone could decipher your code and "steal" your script.
There are a few ways of making your code hard to be stolen, but as i said nothing is bullet-proof.

Javascript 是一种客户端编程语言,因此它可以在客户端的机器上运行,因此您实际上无法对客户端隐藏任何内容。
混淆您的代码是一个很好的解决方案,但这还不够,因为虽然很难,但有人可以破译您的代码并“窃取”您的脚本。
有几种方法可以使您的代码难以被盗,但正如我所说,没有什么是防弹的。

Off the top of my head, one idea is to restrict access to your external js files from outside the page you embed your code in. In that case, if you have

在我的脑海中,一个想法是限制从您嵌入代码的页面外部访问您的外部 js 文件。在这种情况下,如果您有

<script type="text/javascript" src="myJs.js"></script>

and someone tries to access the myJs.jsfile in browser, he shouldn't be granted any access to the script source.
For example, if your page is written in php, you can include the script via the includefunction and let the script decide if it's safe" to return it's source.
In this example, you'll need the external "js" (written in php) file myJs.php:

并且有人试图在浏览器中访问myJs.js文件,他不应该被授予对脚本源的任何访问权限。
例如,如果您的页面是用 php 编写的,您可以通过include函数包含脚本,并让脚本决定返回其源代码是否安全
在此示例中,您将需要外部“js”(用 php 编写) ) 文件myJs.php

<?php
    $URL = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    if ($URL != "my-domain.com/my-page.php")
    die("/\*sry, no acces rights\*/");
?>
// your obfuscated script goes here

that would be included in your main page my-page.php:

这将包含在您的主页my-page.php 中

<script type="text/javascript">
    <?php include "myJs.php"; ?>;
</script> 

This way, only the browser could see the js file contents.

这样,只有浏览器才能看到 js 文件内容。

Another interesting idea is that at the end of your script, you delete the contents of your dom script element, so that after the browser evaluates your code, the code disappears :

另一个有趣的想法是,在脚本的末尾,删除 dom 脚本元素的内容,以便在浏览器评估您的代码后,代码消失:

<script id="erasable" type="text/javascript">
    //your code goes here
    document.getElementById('erasable').innerHTML = "";
</script>

These are all just simple hacks that cannot, and I can't stress this enough : cannot, fully protect your js code, but they can sure piss off someone who is trying to "steal" your code.

这些都只是简单的 hack,不能,我不能强调这一点:不能,完全保护您的 js 代码,但它们肯定会激怒试图“窃取”您的代码的人。

Update:

更新:

I recently came across a very interesting articlewritten by Patrick Weidon how to hide your js code, and he reveals a different approach: you can encode your source code into an image! Sure, that's not bullet proof either, but it's another fencethat you could build around your code.
The idea behind this approach is that most browsers can use the canvas element to do pixel manipulation on images. And since the canvas pixel is represented by 4 values (rgba), each pixel can have a value in the range of 0-255. That means that you can store a character (actual it's ascii code) in every pixel. The rest of the encoding/decoding is trivial.
Thanks, Patrick!

我最近看到Patrick Weid写的一篇关于如何隐藏 js 代码的非常有趣的文章,他揭示了一种不同的方法:您可以将源代码编码为图像!当然,这也不是万无一失,但它是您可以围绕代码构建的另一个围栏
这种方法背后的想法是大多数浏览器可以使用画布元素对图像进行像素操作。由于画布像素由 4 个值 (rgba) 表示,因此每个像素的值可以在 0-255 的范围内。这意味着您可以在每个像素中存储一个字符(实际上是 ascii 代码)。其余的编码/解码是微不足道的。
谢谢,帕特里克!

回答by GWW

The only thing you can do is obfuscateyour code to make it more difficult to read. No matter what you do, if you want the javascript to execute in their browser they'll have to have the code.

你唯一能做的就是混淆你的代码,让它更难阅读。不管你做什么,如果你想让 javascript 在他们的浏览器中执行,他们必须有代码。

回答by sdleihssirhc

Just off the top of my head, you could do something like this (if you can create server-side scripts, which it sounds like you can):

就在我的脑海里,你可以做这样的事情(如果你可以创建服务器端脚本,听起来你可以):

Instead of loading the script like normal, send an AJAX request to a PHP page (it could be anything; I just use it myself). Have the PHP locate the file (maybe on a non-public part of the server), open it with file_get_contents, and return (read: echo) the contents as a string.

不要像往常一样加载脚本,而是向 PHP 页面发送 AJAX 请求(它可以是任何东西;我只是自己使用它)。让 PHP 找到文件(可能在服务器的非公共部分),用 将其打开file_get_contents,然后echo将内容作为字符串返回(读取:)。

When this string returns to the JavaScript, have it create a new scripttag, populate its innerHTMLwith the code you just received, and attach the tag to the page. (You mighthave trouble with this; innerHTMLmay not be what you need, but you can experiment.)

当这个字符串返回给 JavaScript 时,让它创建一个新script标签,innerHTML用你刚收到的代码填充它,并将标签附加到页面上。(您可能对此有问题;innerHTML可能不是您需要的,但您可以进行试验。)

If you do this a lot, you might even want to set up a PHP page that accepts a GET variable with the script's name, so that you can dynamically grab different scripts using the same PHP. (Maybe you could use POST instead, to make it just a little harder for other people to see what you're doing. I don't know.)

如果您经常这样做,您甚至可能希望设置一个 PHP 页面,该页面接受带有脚本名称的 GET 变量,以便您可以使用相同的 PHP 动态获取不同的脚本。(也许你可以改用 POST,让其他人更难看到你在做什么。我不知道。)

EDIT:I thought you were only trying to hide the locationof the script. This obviously wouldn't help much if you're trying to hide the script itself.

编辑:我以为你只是想隐藏脚本的位置。如果您试图隐藏脚本本身,这显然无济于事。

回答by Martin Jespersen

Forget it, this is not doable.

算了,这是不可行的。

No matter what you try it will not work. All a user needs to do to discover your code and it's location is to look in the net tab in firebugor use fiddlerto see what requests are being made.

不管你怎么尝试都行不通。用户发现您的代码及其位置所需要做的就是查看firebug中的 net 选项卡或使用fiddler查看正在发出的请求。

回答by Lionel Chan

Google Closure Compiler, YUI compressor, Minify, /Packer/... etc, are options for compressing/obfuscating your JS codes. But none of them can help you from hiding your code from the users.

Google Closure CompilerYUI 压缩器Minify/Packer/... 等,是用​​于压缩/混淆 JS 代码的选项。但是它们都不能帮助您向用户隐藏您的代码。

Anyone with decent knowledge can easily decode/de-obfuscate your code using tools like JS Beautifier. You name it.

任何有丰富知识的人都可以使用JS Beautifier 之类的工具轻松解码/去混淆您的代码。你说出它的名字。

So the answer is, you can always make your code harder to read/decode, but for sure there is no way to hide.

所以答案是,你总是可以让你的代码更难阅读/解码,但肯定没有办法隐藏。

回答by darioo

From my knowledge, this is not possible.

据我所知,这是不可能的。

Your browser has to have access to JS files to be able to execute them. If the browser has access, then browser's user also has access.

您的浏览器必须能够访问 JS 文件才能执行它们。如果浏览器具有访问权限,则浏览器的用户也具有访问权限。

If you password protect your JS files, then the browser won't be able to access them, defeating the purpose of having JS in the first place.

如果你用密码保护你的 JS 文件,那么浏览器将无法访问它们,这违背了拥有 JS 的初衷。

回答by ejectamenta

I think the only way is to put required data on the server and allow only logged-in user to access the data as required (you can also make some calculations server side). This wont protect your javascript code but make it unoperatable without the server side code

我认为唯一的方法是将所需的数据放在服务器上,并仅允许登录用户根据需要访问数据(您也可以在服务器端进行一些计算)。这不会保护您的 javascript 代码,但会使其在没有服务器端代码的情况下无法运行

回答by danicotra

As I said in the comment I left on gion_13 answer before (please read), you really can't. Not with javascript.

正如我之前在 gion_13 答案上留下的评论中所说的那样(请阅读),你真的不能。不是用 javascript。

If you don't want the code to be available client-side (= stealable without great efforts), my suggestion would be to make use of PHP (ASP,Python,Perl,Ruby,JSP + Java-Servlets) that is processed server-side and only the results of the computation/code execution are served to the user. Or, if you prefer, even Flash or a Java-Applet that let client-side computation/code execution but are compiled and thus harder to reverse-engine (not impossible thus).

如果您不希望代码在客户端可用(= 无需付出很大努力即可窃取),我的建议是使用处理服务器的 PHP(ASP、Python、Perl、Ruby、JSP + Java-Servlets) -side,只有计算/代码执行的结果才提供给用户。或者,如果您愿意,甚至可以使用 Flash 或 Java-Applet,它们允许客户端计算/代码执行但经过编译,因此更难逆向引擎(因此并非不可能)。

Just my 2 cents.

只有我的 2 美分。

回答by S. Francis

I agree with everyone else here: With JS on the client, the cat is out of the bag and there is nothing completely foolproof that can be done.

我同意这里的其他人的观点:在客户端上使用 JS 时,猫已经不在话下,没有什么可以做到完全万无一失。

Having said that; in some cases I do this to put some hurdles in the way of those who want to take a look at the code. This is how the algorithm works (roughly)

话说回来; 在某些情况下,我这样做是为了给那些想要查看代码的人设置一些障碍。这就是算法的工作原理(大致)

  1. The server creates 3 hashed and salted values. One for the current timestamp, and the other two for each of the next 2 seconds. These values are sent over to the client via Ajax to the client as a comma delimited string; from my PHP module. In some cases, I think you can hard-bake these values into a script section of HTML when the page is formed, and delete that script tag once the use of the hashes is over The server is CORS protected and does all the usual SERVER_NAME etc check (which is not much of a protection but at least provides some modicum of resistance to script kiddies).

  2. Also it would be nice, if the the server checks if there was indeed an authenticated user's client doing this

  3. The client then sends the same 3 hashed values back to the server thru an ajax call to fetch the actual JS that I need. The server checks the hashes against the current time stamp there... The three values ensure that the data is being sent within the 3 second window to account for latency between the browser and the server

  4. The server needs to be convinced that one of the hashes is matched correctly; and if so it would send over the crucial JS back to the client. This is a simple, crude "One time use Password" without the need for any database at the back end.

  5. This means, that any hacker has only the 3 second window period since the generation of the first set of hashes to get to the actual JS code.

  6. The entire client code can be inside an IIFE function so some of the variables inside the client are even more harder to read from the Inspector console

    This is not any deep solution: A determined hacker can register, get an account and then ask the server to generate the first three hashes; by doing tricks to go around Ajax and CORS; and then make the client perform the second call to get to the actual code -- but it is a reasonable amount of work.

  1. 服务器创建 3 个散列和加盐值。一个用于当前时间戳,另外两个用于接下来的 2 秒中的每一秒。这些值作为逗号分隔的字符串通过 Ajax 发送到客户端;从我的 PHP 模块。在某些情况下,我认为您可以在页面形成时将这些值硬烘焙到 HTML 的脚本部分中,并在散列的使用结束后删除该脚本标记 服务器受 CORS 保护并执行所有常见的 SERVER_NAME 等检查(这不是一种保护,但至少对脚本小子提供了一些抵抗力)。

  2. 如果服务器检查是否确实有经过身份验证的用户的客户端这样做,那也很好

  3. 然后,客户端通过 ajax 调用将相同的 3 个散列值发送回服务器,以获取我需要的实际 JS。服务器根据当前时间戳检查哈希值......这三个值确保数据在 3 秒窗口内发送,以解决浏览器和服务器之间的延迟

  4. 服务器需要确信其中一个哈希值匹配正确;如果是这样,它会将关键的 JS 发送回客户端。这是一个简单粗暴的“一次性使用密码”,不需要后端的任何数据库。

  5. 这意味着,自第一组散列生成以来,任何黑客只有 3 秒的窗口期才能到达实际的 JS 代码。

  6. 整个客户端代码可以在 IIFE 函数中,因此客户端中的一些变量更难从 Inspector 控制台读取

    这不是什么深层次的解决方案:一个有决心的黑客可以注册,获得一个帐户,然后要求服务器生成前三个哈希值;通过做一些技巧来绕过 Ajax 和 CORS;然后让客户端执行第二次调用以获取实际代码——但这是一个合理的工作量。

Moreover, if the Salt used by the server is based on the login credentials; the server may be able to detect who is that user who tried to retreive the sensitive JS (The server needs to do some more additional work regarding the behaviour of the user AFTER the sensitive JS was retreived, and block the person if the person, say for example, did not do some other activity which was expected)

此外,如果服务器使用的 Salt 是基于登录凭据的;服务器可能能够检测到谁是试图检索敏感 JS 的用户(服务器需要对检索敏感 JS 后用户的行为做一些额外的工作,如果有人说,则阻止该人例如,没有做一些其他预期的活动)

An old, crude version of this was done for a hackathon here: http://planwithin.com/demo/tadr.htmlThat wil not work in case the server detects too much latency, and it goes beyond the 3 second window period

一个旧的、粗糙的版本是为这里的黑客马拉松完成的:http: //planwithin.com/demo/tadr.html 如果服务器检测到太多延迟,它就不起作用,它超过了 3 秒窗口期

回答by sybercoda

You can also set up a mime type for application/JavaScript to run as PHP, .NET, Java, or whatever language you're using. I've done this for dynamic CSS files in the past.

您还可以为应用程序/JavaScript 设置 mime 类型以作为 PHP、.NET、Java 或您使用的任何语言运行。我过去曾为动态 CSS 文件做过这件事。