【问题标题】:Disable editing of javascript from chrome console?禁用从 chrome 控制台编辑 javascript?
【发布时间】:2012-10-22 09:17:43
【问题描述】:

所以,我今天才注意到您显然可以在 chrome 控制台中运行 javascript。我不知道你能做到这一点。真的很酷。

在我的 rails 应用程序中,我有一个外部 javascript 页面。该页面上的一些变量我希望是全局的,以便 JS 文件中的所有函数都可以访问它们。例如,我有一张地图,我希望地图对象在 javascript 文件中是全局的,因为这样我的所有函数都可以访问一个地图变量而不是创建自己的地图变量,而且我可以将复杂的操作分解为更小的函数。

这一切都很好,我知道该怎么做,而且效果很好。我现在的问题是,我可以保护变量不受外部影响吗?例如,您可以从 chrome 控制台更改所有 javascript 类变量的值。以及地图中的方法是可访问和可执行的。我已将地图设置锁定在其中一个页面上,因此它不可缩放或可移动,但是从控制台我可以简单地说map.setZoom(11),地图将缩放到11..我可以输入map.dragable = true,然后你可以拖动地图..我真的不喜欢这个..

这还不算太糟糕,但就像用户启用地图拖动和缩放并不是世界上最糟糕的事情一样......但我仍然想禁用它。有任何想法吗?

编辑

感谢大家的回答和cmets。我想我只会诉诸不将任何可能变成恶意的东西放入我的 javascript 中,并做一些事情,例如将我的 map 变量传递给必要的函数以减慢人们的速度。

【问题讨论】:

  • 您可以将所有内容包装在一个新的函数范围内。
  • 也就是说,确实没有理由使用全局变量。最好在必要时更改您的方法以将地图作为参数。
  • 嗯...这似乎是更好的编码标准?

标签: javascript google-chrome console javascript-security


【解决方案1】:

您可以使用立即调用函数 (IIFE) 表达式来防止您的变量和函数在全局范围内公开:

var a = 10;

(function() {
    var b = 20;
})();

window.a 可让您查看和修改a,但您无法使用b 执行此操作:

Try it out here

我非常确定有一种方法可以使用 Inspector 编辑 b,但我还没有花时间弄清楚。不要浪费时间试图阻止用户修改他们可以查看的代码。

【讨论】:

  • 编辑中的精彩之处。此外,不要在 JavaScript 中允许/期望敏感数据。
  • 链接失效
【解决方案2】:

你不能。即使您将它们包装成匿名函数,用户也可以通过调试器访问它们。作为最后的手段,他可以简单地将您的流量拦截到他自己的机器上,并用其他东西替换您的 JavaScript。

底线:浏览器中的 JavaScript 是 客户端。客户可以为所欲为。

【讨论】:

    【解决方案3】:

    尝试做这样的事情:

    (function(){
       //All of your current code
    })();
    

    还有一点需要注意——Chrome 开发者工具还允许您编辑 javascript(不是服务器上的 javascript 文件,只是当前正在运行的副本。)转到 Chrome Dev Tools->Sources,您可以编辑 javascript 文件.

    【讨论】:

      【解决方案4】:

      你不能。您说您需要在全球范围内定义地图,这意味着每个人都可以访问它。 你可以在不同的范围内定义你的地图,然后只定义“公共”的东西:

      (function() {
          var map = new Map();
          window.myMap = {
              goTo: function(lat, lng) {
                  map.goTo(lat, lng);
              }
          };
      })();
      

      【讨论】:

        【解决方案5】:

        根据您的架构,有几种方法可以实现这一点。使用此方法创建具有公共和私有属性的可重用组件:

        var protectedScope = function () {
            var protected_var = 'protected';
            this.showProtected = function () {
                return protected_var;
            }
            this.public = 'public';               
        };
        var myObject = new protectedScope();
        
        console.log('Public var: '+myObject.public); // outputs "public"
        console.log('Protected via accessor: '+myObject.showProtected ()); // outputs "private"
        console.log('Protected var: '+myObject.protected); // outputs undefined
        

        使用var 关键字声明的任何变量或函数实际上都是私有的。任何使用this.name 机制的变量或函数都将是“公共的”。

        了解这种结构不是真正的公共或私有的,这样的概念不是语言的一部分。仍然有一些方法可以获取这些变量,并且总是可以查看源代码。清楚一点; 这是一个代码组织概念,而不是一个安全概念。 Chrome 拥有这个开发者控制台已经有一段时间了,其他主要的用户代理正在转向包括类似的工具(或者已经这样做了)。还有像 Firebug 这样的工具,它允许用户完全访问您的 javascript 运行时环境。这根本不是开发者可以控制的领域。

        在这里试试:http://jsfiddle.net/cf2kS/

        更多阅读

        【讨论】:

        • 如果我编辑 protectedScope 原型并为私有变量添加我自己的自定义 getter、setter 会怎样?
        • 这些伪私有变量的问题在于,您必须在代码主体中构建任何 getter 或 setter —— 您不能使用原型来访问伪私有变量。这个概念之所以有效,是因为您正在函数体中形成闭包。当您通过其原型添加或修改函数时,该代码不会关闭内部范围,因此它无法访问该范围内的变量。如果你在 body 中使用了this.myVal = 1;,原型函数可以访问它,但这也暴露在外部。
        【解决方案6】:
        Object.defineProperty(map, 'zoom', {value:1});
        

        Object.defineProperty(map, 'zoom',{
            set: function(){console.warn('Access denied!');},
            get: function(){return 1;}
            }); 
        

        demo

        Object.defineProperty(Object.prototype, 'protect', {
            value:  function(ignore){
                var childObjects = [], ignore = ignore || [];
                ignore.push(this);      
                if(this instanceof MimeType)return; //Chrome Fix //window.clientInformation.mimeTypes[0].enabledPlugin[0] !== window.clientInformation.mimeTypes[0]
                for(var prop in this){
                    if(typeof this[prop] === "unknown")continue; //IE fix
                    if(this[prop] instanceof Object){
                        var skip = false;
                        for(var i in ignore)
                            if(ignore[i]===this[prop]){
                                skip = true;
                                break;
                            }
                        if(!skip)childObjects.push(prop);   
                    }       
                    var d = Object.getOwnPropertyDescriptor(this, prop);
                    if(!d || !d.configurable || !d.writable)continue;
                    var that = this;
                    (function(){
                        var temp = that[prop];
                        delete that[prop];
                        Object.defineProperty(that, prop,{
                            set: function(){console.warn('Access denied!');},
                            get: function(){return temp;}
                        });
                    })();
                }
                for(var i = 0;i<childObjects.length;i++)
                    this[childObjects[i]].protect(ignore);
            }  
        });
        this.onload=function(){this.protect();} //example
        

        demo

        【讨论】:

        • hmm... 这样就可以防止用户更改缩放属性然后.. 但是我不是必须对每个全局对象的每个属性都有这样的声明吗?这让我有点阻止用户更改地图缩放,这实际上非常好,因为如果更改地图缩放很糟糕,这会阻止他们,但仍然会离开控制台和其他一切
        • @user1759942 参见第三种方法,即保护一切跨浏览器,不仅来自控制台,还来自地址栏的javascript:xy
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        • 1970-01-01
        • 2011-03-28
        • 1970-01-01
        相关资源
        最近更新 更多