如何保护 JavaScript 文件?
我知道隐藏源代码是不可能的,但是,例如,如果我必须将 JavaScript 文件从 CDN 链接到网页,并且我不希望人们知道该脚本的位置和/或内容,是这样吗?可能的?
例如,要从网站链接脚本,我们使用:
<script type="text/javascript" src="http://somedomain.example/scriptxyz.js">
</script>
现在,是否可以向用户隐藏脚本的来源,或者隐藏脚本内容并仍然在网页上使用它?
例如,将其保存在需要密码才能访问文件的私人 CDN 中,这可行吗?如果没有,怎样才能得到我想要的东西?
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?
For example, to link a script from a website, we use:
<script type="text/javascript" src="http://somedomain.example/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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
好问题,答案简单:你不能!
JavaScript 是一种客户端编程语言,因此它在客户端的计算机上运行,因此您实际上无法向客户端隐藏任何内容。
混淆代码是一个很好的解决方案,但这还不够,因为尽管这很困难,但有人可以破译您的代码并“窃取”您的脚本。
有几种方法可以使您的代码难以被窃取,但正如我所说,没有什么是万无一失的。
我突然想到,一个想法是限制从嵌入代码的页面外部访问外部 js 文件。在这种情况下,如果您有
并且有人尝试访问
myJs.js
在浏览器中的文件中,他不应该被授予对脚本源的任何访问权限。例如,如果您的页面是用 PHP 编写的,您可以通过
include
函数包含脚本,并让脚本决定返回其源代码是否安全”。在此示例中,您需要外部“js”(用 PHP 编写)文件
myJs.php
:该文件将包含在您的主页
my-page.php
中:这样,只有浏览器才能看到js文件内容。
另一个有趣的想法是,在脚本末尾,您删除 dom 脚本元素的内容,以便在浏览器评估您的代码后,代码消失:
这些都只是简单的黑客,不能,我不能强调这已经足够了:不能完全保护你的 js 代码,但他们肯定会激怒那些试图“窃取”你的代码的人。
更新:
我最近发现一篇非常有趣的文章 由 Patrick Weid 撰写,介绍如何隐藏 js 代码,他揭示了一种不同的方法方法:您可以将源代码编码成图像!当然,这也不是防弹的,但它是您可以围绕代码构建的另一个栅栏。
这种方法背后的想法是,大多数浏览器可以使用 canvas 元素对图像进行像素操作。由于画布像素由 4 个值(rgba)表示,因此每个像素可以具有 0-255 范围内的值。这意味着您可以在每个像素中存储一个字符(实际上是 ascii 代码)。其余的编码/解码是微不足道的。
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.
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
and someone tries to access the
myJs.js
file 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
include
function 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
:that would be included in your main page
my-page.php
:This way, only the browser could see the js file contents.
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:
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.
Update:
I recently came across a very interesting article written by Patrick Weid on 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 fence that 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.
您唯一能做的就是混淆您的代码以使其更难以阅读。无论您做什么,如果您希望 JavaScript 在他们的浏览器中执行,他们就必须拥有代码。
The only thing you can do is obfuscate your 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.
就在我的脑海中,你可以做这样的事情(如果你可以创建服务器端脚本,听起来你可以):
而不是像平常一样加载脚本,而是向 PHP 页面发送 AJAX 请求(它可以是任何东西;我自己就用它)。让 PHP 找到该文件(可能位于服务器的非公共部分),使用 file_get_contents 打开它,然后以字符串形式返回(读取:echo)内容。
当该字符串返回到 JavaScript 时,让它创建一个新的
script
标记,用您刚刚收到的代码填充其innerHTML
,并将该标记附加到页面。 (您可能对此有困难;innerHTML
可能不是您所需要的,但您可以尝试一下。)如果您经常这样做,您甚至可能想要设置接受带有脚本名称的 GET 变量的 PHP 页面,以便您可以使用相同的 PHP 动态抓取不同的脚本。 (也许你可以使用 POST 来代替,让其他人更难看到你在做什么。我不知道。)
编辑:我以为你只是想隐藏脚本的位置。如果您试图隐藏脚本本身,这显然没有多大帮助。
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.When this string returns to the JavaScript, have it create a new
script
tag, populate itsinnerHTML
with the code you just received, and attach the tag to the page. (You might have trouble with this;innerHTML
may not be what you need, but you can experiment.)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.)
EDIT: I thought you were only trying to hide the location of the script. This obviously wouldn't help much if you're trying to hide the script itself.
Google Closure 编译器、YUI 压缩器,Minify,/Packer/...等是压缩/混淆 JS 代码的选项。但它们都无法帮助您向用户隐藏代码。
任何有足够知识的人都可以使用 JS Beautifier 等工具轻松解码/反混淆您的代码。你说出它的名字。
所以答案是,你总是可以让你的代码更难阅读/解码,但肯定没有办法隐藏。
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.
Anyone with decent knowledge can easily decode/de-obfuscate your code using tools like JS Beautifier. You name it.
So the answer is, you can always make your code harder to read/decode, but for sure there is no way to hide.
算了,这也是办不到的。
无论你尝试什么,都不会起作用。用户需要做的就是在 firebug 中的 net 选项卡中查找或使用 fiddler 查看正在发出哪些请求。
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 firebug or use fiddler to see what requests are being made.
据我所知,这是不可能的。
您的浏览器必须能够访问 JS 文件才能执行它们。如果浏览器具有访问权限,则浏览器的用户也具有访问权限。
如果你用密码保护你的 JS 文件,那么浏览器将无法访问它们,这就违背了拥有 JS 的初衷。
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.
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.
我认为唯一的方法是将所需的数据放在服务器上,并仅允许登录用户根据需要访问数据(您也可以在服务器端进行一些计算)。这不会保护您的 javascript 代码,但会使其在没有服务器端代码的情况下无法运行
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
我同意这里其他人的观点:在客户端使用 JS,秘密就已经泄露了,没有什么是完全万无一失的。
话虽如此;在某些情况下,我这样做是为了给那些想要查看代码的人设置一些障碍。这就是算法的工作原理(大致)
服务器创建 3 个哈希值和加盐值。一个用于当前时间戳,另外两个用于接下来 2 秒的每一秒。这些值通过 Ajax 以逗号分隔的字符串形式发送到客户端;来自我的 PHP 模块。在某些情况下,我认为您可以在页面形成时将这些值硬烘焙到 HTML 的脚本部分中,并在散列的使用结束后删除该脚本标记服务器受 CORS 保护并执行所有常见的 SERVER_NAME 等操作检查(这不是太多的保护,但至少提供了一些对脚本小子的抵抗力)。
如果服务器检查是否确实有经过身份验证的用户客户端在执行此操作,那就太好了
客户端然后通过 ajax 调用将相同的 3 个哈希值发送回服务器以获取我需要的实际 JS。服务器根据当前时间戳检查哈希值...这三个值确保数据在 3 秒窗口内发送,以考虑浏览器和服务器之间的延迟
服务器需要确信一个哈希值是
匹配正确;如果是这样,它将发送回关键的 JS
给客户。这是一个简单粗暴的“一次性密码”
后端不需要任何数据库。
这意味着,自第一组哈希值生成以来,任何黑客都只有 3 秒的窗口期来获取实际的 JS 代码。
整个客户端代码可以位于 IIFE 函数内,因此客户端内的某些变量更难从 Inspector 控制台读取
这不是任何深入的解决方案:坚定的黑客可以注册,获得一个帐户,然后要求服务器生成前三个哈希值;通过一些技巧来绕过 Ajax 和 CORS;然后让客户端执行第二次调用以获取实际代码——但这是一个合理的工作量。
此外,如果服务器使用的Salt是基于登录凭据的;服务器也许能够检测到谁是试图检索敏感JS的用户(服务器需要在检索敏感JS之后对用户的行为做一些额外的工作,并阻止该人,如果该人,例如例如,没有进行预期的其他活动)
这里为黑客马拉松完成了一个旧的、粗略的版本:http://planwithin.com/demo/tadr.html 如果服务器检测到太多延迟并且超出了 3 秒窗口期,则该方法将不起作用
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.
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)
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).
Also it would be nice, if the the server checks if there was indeed an authenticated user's client doing this
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
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.
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.
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.
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)
An old, crude version of this was done for a hackathon here: http://planwithin.com/demo/tadr.html That wil not work in case the server detects too much latency, and it goes beyond the 3 second window period
正如我之前在 gion_13 答案上留下的评论中所说(请阅读),你真的不能。不是用 JavaScript。
如果您不希望代码在客户端可用(=无需付出很大努力即可窃取),
我的建议是使用在服务器端处理的 PHP(ASP、Python、Perl、Ruby、JSP + Java-Servlet),并且仅将计算/代码执行的结果提供给用户。或者,如果您愿意,甚至可以使用允许客户端计算/代码执行但经过编译的 Flash 或 Java-Applet,因此更难进行反向引擎(因此并非不可能)。
只是我的2分钱。
As I said in the comment I left on gion_13 answer before (please read), you really can't. Not with 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).
Just my 2 cents.
您还可以为应用程序/JavaScript 设置 MIME 类型,以作为 PHP、.NET、Java 或您正在使用的任何语言运行。我过去曾对动态 CSS 文件这样做过。
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.
我知道现在回答这个问题是错误的,但我只是想到了一些
我知道可能会有压力的事情,但至少它可能仍然有效
现在的秘诀是创造 许多服务器端编码脚本,它们必须是可解码的(例如,用数字替换所有元音并将字母“a”添加到每个辅音的脚本,以便单词“bat”变成ba1ta)然后创建一个脚本将在编码脚本之间进行随机化,并使用正在使用的编码脚本的名称创建一个 cookie(快速提示:尽量不要使用 cookie 的编码脚本的实际名称,例如,如果我们的 cookie 名称为“encoding_script_being_used”,并且随机化脚本选择名为 MD10 的编码脚本,尽量不要使用 MD10 作为 cookie 的值,而是使用“encoding_script4567656”,只是为了防止猜测)然后在创建 cookie 后,另一个脚本将检查名为“encoding_script_being_used”的 cookie 并获取值,然后它将确定正在使用什么编码脚本。
现在,在编码脚本之间进行随机化的原因是服务器端语言将随机化使用哪个脚本来解码 javascript.js,然后创建一个会话或 cookie 以了解使用了哪个编码脚本
那么服务器端语言也会对你的 javascript .js 进行编码并将其作为 cookie
so now let me summarize with an example
PHP randomizes between a list of encoding scripts and encrypts javascript.js then it create a cookie telling the client side language which encoding script was used then client side language decodes the javascript.js cookie(which is obviously encoded)
这样人们就无法窃取你的代码,
但我不建议这样做,因为
I know that this is the wrong time to be answering this question but i just thought of something
i know it might be stressful but atleast it might still work
Now the trick is to create a lot of server side encoding scripts, they have to be decodable(for example a script that replaces all vowels with numbers and add the letter 'a' to every consonant so that the word 'bat' becomes ba1ta) then create a script that will randomize between the encoding scripts and create a cookie with the name of the encoding script being used (quick tip: try not to use the actual name of the encoding script for the cookie for example if our cookie is name 'encoding_script_being_used' and the randomizing script chooses an encoding script named MD10 try not to use MD10 as the value of the cookie but 'encoding_script4567656' just to prevent guessing) then after the cookie has been created another script will check for the cookie named 'encoding_script_being_used' and get the value, then it will determine what encoding script is being used.
Now the reason for randomizing between the encoding scripts was that the server side language will randomize which script to use to decode your javascript.js and then create a session or cookie to know which encoding scripts was used
then the server side language will also encode your javascript .js and put it as a cookie
so now let me summarize with an example
PHP randomizes between a list of encoding scripts and encrypts javascript.js then it create a cookie telling the client side language which encoding script was used then client side language decodes the javascript.js cookie(which is obviously encoded)
so people can't steal your code
but i would not advise this because
使用 nwjs 我认为很有帮助,它可以编译到 bin 然后你可以用它来制作 win、mac 和 linux 应用程序
use nwjs i think helpful it can compile to bin then you can use it to make win,mac and linux application
如果您不想暴露算法中最敏感的部分,则此方法部分有效。
创建 WebAssembly 模块 (.wasm),导入它们,并仅公开您的 JS 等...工作流程。通过这种方式,算法得到了保护,因为将汇编代码恢复为更人类可读的格式是极其困难的。
生成 wasm 模块并导入 correclty 后,您可以像平常一样使用代码:
This method partially works if you do not want to expose the most sensible part of your algorithm.
Create WebAssembly modules (.wasm), import them, and expose only your JS, etc... workflow. In this way the algorithm is protected since it is extremely difficult to revert assembly code into a more human readable format.
After having produced the wasm module and imported correclty, you can use your code as you normallt do: