Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Facebook如何禁用浏览器';s的集成开发工具?_Javascript_Facebook_Google Chrome Devtools - Fatal编程技术网

Javascript Facebook如何禁用浏览器';s的集成开发工具?

Javascript Facebook如何禁用浏览器';s的集成开发工具?,javascript,facebook,google-chrome-devtools,Javascript,Facebook,Google Chrome Devtools,很明显,由于最近的诈骗,开发者工具被人们用来发布垃圾邮件,甚至被用来“黑客”帐户。Facebook已经屏蔽了开发者工具,我甚至不能使用控制台 var is; Object.defineProperty(Object.prototype,"_lastResult",{ get:function(){ return this._lR; }, set:function(v){ if (typeof this._commandLineAPIImpl=="ob

很明显,由于最近的诈骗,开发者工具被人们用来发布垃圾邮件,甚至被用来“黑客”帐户。Facebook已经屏蔽了开发者工具,我甚至不能使用控制台

var is;
Object.defineProperty(Object.prototype,"_lastResult",{
   get:function(){
       return this._lR;
   },
   set:function(v){
       if (typeof this._commandLineAPIImpl=="object") is=this;
       this._lR=v;
   }
});
setTimeout(function(){
   var ev=is._evaluateAndWrap;
   is._evaluateAndWrap=function(){
       var res=ev.apply(is,arguments);
       console.log();
       if (arguments[2]==="completion") {
           //This is the path you end up when a user types in the console and autocompletion get's evaluated

           //Chrome expects a wrapped result to be returned from evaluateAndWrap.
           //You can use `ev` to generate an object yourself.
           //In case of the autocompletion chrome exptects an wrapped object with the properties that can be autocompleted. e.g.;
           //{iGetAutoCompleted: true}
           //You would then go and return that object wrapped, like
           //return ev.call (is, '', '({test:true})', 'completion', true, false, true);
           //Would make `test` pop up for every autocompletion.
           //Note that syntax as well as every Object.prototype property get's added to that list later,
           //so you won't be able to exclude things like `while` from the autocompletion list,
           //unless you wou'd find a way to rewrite the getCompletions function.
           //
           return res; //Return the autocompletion result. If you want to break that, return nothing or an empty object
       } else {
           //This is the path where you end up when a user actually presses enter to evaluate an expression.
           //In order to return anything as normal evaluation output, you have to return a wrapped object.

           //In this case, we want to return the generated remote object. 
           //Since this is already a wrapped object it would be converted if we directly return it. Hence,
           //`return result` would actually replicate the very normal behaviour as the result is converted.
           //to output what's actually in the remote object, we have to stringify it and `evaluateAndWrap` that object again.`
           //This is quite interesting;
           return ev.call (is, null, '(' + JSON.stringify (res) + ')', "console", true, false, true)
       }
   };
},0);

他们是怎么做到的,但Facebook已经证明他们错了

只要进入Facebook,打开开发者工具,在控制台中输入一个字符,就会弹出这个警告。不管你投入了什么,它都不会被执行

这怎么可能

他们甚至在控制台中阻止了自动完成:


我无法让它在任何页面上触发它。更强大的版本可以做到这一点:

window.console.log = function(){
    console.error('The developer console is temp...');
    window.console.log = function() {
        return false;
    }
}

console.log('test');
要设置输出样式,请执行以下操作:


编辑思考有一个正确的想法:

我是Facebook的安全工程师,这是我的错。我们正在对一些用户进行测试,看看它是否可以减缓一些攻击,在这些攻击中,用户被诱骗向浏览器控制台粘贴(恶意)JavaScript代码

要明确的是:试图阻止黑客客户端是一个普遍的问题; 这是为了防止发生意外

如果您最终进入了测试组,并且对此感到恼火,请道歉。 我试图使旧的选择退出页面(现在)尽可能简单,同时仍然足够吓人,至少可以阻止一些受害者

实际代码非常类似于;我们的有点复杂,没有充分的理由

Chrome将所有控制台代码包装在

with ((console && console._commandLineAPI) || {}) {
  <code goes here>
}
这是,但那是最重要的 主要技巧



结语:Chrome团队认为从用户端JS击败控制台是一个错误,这使得这项技术无效。之后,又增加了额外的保护

我使用Chrome开发者工具找到了Facebook的控制台buster脚本。以下是脚本,为了可读性做了一些小改动。我已经删除了我无法理解的部分:

Object.defineProperty(window, "console", {
    value: console,
    writable: false,
    configurable: false
});

var i = 0;
function showWarningAndThrow() {
    if (!i) {
        setTimeout(function () {
            console.log("%cWarning message", "font: 2em sans-serif; color: yellow; background-color: red;");
        }, 1);
        i = 1;
    }
    throw "Console is disabled";
}

var l, n = {
        set: function (o) {
            l = o;
        },
        get: function () {
            showWarningAndThrow();
            return l;
        }
    };
Object.defineProperty(console, "_commandLineAPI", n);
Object.defineProperty(console, "__commandLineAPI", n);
这样,控制台自动完成将以静默方式失败,而在控制台中键入的语句将无法执行(将记录异常)

参考资料:


除了重新定义控制台之外。_commandLineAPI, 还有其他一些方法可以在WebKit浏览器上侵入InjectedScriptHost,以防止或改变输入到开发人员控制台的表达式的计算

编辑:

Chrome在过去的版本中修复了此问题。-这一定是在2015年2月之前,因为我当时创建了要点

这是另一种可能性。这一次,我们将在上面的一个级别直接连接到
InjectedScript
,而不是
InjectedScriptHost
,而不是以前的版本

这很好,因为您可以直接使用monkey patch
InjectedScript.\u evaluateAndWrap
,而不必依赖
InjectedScriptHost.evaluate
,因为这样可以更细粒度地控制应该发生的事情

另一件非常有趣的事情是,我们可以在计算表达式时截取内部结果,并将其返回给用户,而不是正常的行为

这是一段代码,当用户在控制台中评估某个内容时,它会返回内部结果

var is;
Object.defineProperty(Object.prototype,"_lastResult",{
   get:function(){
       return this._lR;
   },
   set:function(v){
       if (typeof this._commandLineAPIImpl=="object") is=this;
       this._lR=v;
   }
});
setTimeout(function(){
   var ev=is._evaluateAndWrap;
   is._evaluateAndWrap=function(){
       var res=ev.apply(is,arguments);
       console.log();
       if (arguments[2]==="completion") {
           //This is the path you end up when a user types in the console and autocompletion get's evaluated

           //Chrome expects a wrapped result to be returned from evaluateAndWrap.
           //You can use `ev` to generate an object yourself.
           //In case of the autocompletion chrome exptects an wrapped object with the properties that can be autocompleted. e.g.;
           //{iGetAutoCompleted: true}
           //You would then go and return that object wrapped, like
           //return ev.call (is, '', '({test:true})', 'completion', true, false, true);
           //Would make `test` pop up for every autocompletion.
           //Note that syntax as well as every Object.prototype property get's added to that list later,
           //so you won't be able to exclude things like `while` from the autocompletion list,
           //unless you wou'd find a way to rewrite the getCompletions function.
           //
           return res; //Return the autocompletion result. If you want to break that, return nothing or an empty object
       } else {
           //This is the path where you end up when a user actually presses enter to evaluate an expression.
           //In order to return anything as normal evaluation output, you have to return a wrapped object.

           //In this case, we want to return the generated remote object. 
           //Since this is already a wrapped object it would be converted if we directly return it. Hence,
           //`return result` would actually replicate the very normal behaviour as the result is converted.
           //to output what's actually in the remote object, we have to stringify it and `evaluateAndWrap` that object again.`
           //This is quite interesting;
           return ev.call (is, null, '(' + JSON.stringify (res) + ')', "console", true, false, true)
       }
   };
},0);
这有点冗长,但我想我在里面加了一些评论

因此,通常情况下,如果用户对
[1,2,3,4]
进行求值,则会得到以下输出:

monkeypatching
InjectedScript.\u evaluateAndWrap
对同一表达式求值后,将给出以下输出:

正如您看到的,指示输出的小左箭头仍然存在,但这次我们得到了一个对象。其中,表达式的结果,数组
[1,2,3,4]
表示为一个对象,并描述其所有属性

我建议尝试评估这个表达式和那个表达式,包括那些产生错误的表达式。这很有趣

此外,请查看
is
-
InjectedScriptHost
-对象。它提供了一些可以使用的方法,并对inspector的内部结构有了一些了解

当然,您可以截取所有这些信息,并将原始结果返回给用户

只需将else路径中的return语句替换为
console.log(res)
后面的
return res
。然后你会得到以下结果

编辑结束


这是以前的版本,由谷歌修复。因此不再是一种可能的方式

其中之一是连接到
函数.prototype.call

Chrome通过
call
将其eval函数与
InjectedScriptHost
作为
thisArg

var result=evalFunction.call(对象、表达式)

有鉴于此,您可以侦听
调用的
thisArg
作为
求值
,并获取对第一个参数的引用(
InjectedScriptHost

例如,您可以抛出一个错误,说明评估被拒绝

下面是一个示例,其中输入的表达式在传递给
evaluate
函数之前会传递给CoffeeScript编译器


Netflix也实现了这一功能

(function() {
    try {
        var $_console$$ = console;
        Object.defineProperty(window, "console", {
            get: function() {
                if ($_console$$._commandLineAPI)
                    throw "Sorry, for security reasons, the script console is deactivated on netflix.com";
                return $_console$$
            },
            set: function($val$$) {
                $_console$$ = $val$$
            }
        })
    } catch ($ignore$$) {
    }
})();

他们只是覆盖控制台。_commandLineAPI
抛出安全错误。

这实际上是可能的,因为Facebook能够做到这一点。 当然,不是真正的web开发工具,而是在控制台中执行Javascript

见此:

不过,这确实没什么用,因为还有其他方法可以绕过这种类型的客户端安全性

当您说它是客户端时,它是在服务器的控制之外发生的,因此您对此无能为力。如果你问Facebook为什么仍然这样做,这并不是为了安全,而是为了保护不懂javascript的普通用户不让他们运行代码
(function() {
    try {
        var $_console$$ = console;
        Object.defineProperty(window, "console", {
            get: function() {
                if ($_console$$._commandLineAPI)
                    throw "Sorry, for security reasons, the script console is deactivated on netflix.com";
                return $_console$$
            },
            set: function($val$$) {
                $_console$$ = $val$$
            }
        })
    } catch ($ignore$$) {
    }
})();
  Object.getOwnPropertyNames(console).filter(function(property) {
     return typeof console[property] == 'function';
  }).forEach(function (verb) {
     console[verb] =function(){return 'Sorry, for security reasons...';};
  });
if(!window.console) window.console = {};
var methods = ["log", "debug", "warn", "info", "dir", "dirxml", "trace", "profile"];
for(var i=0;i<methods.length;i++){
    console[methods[i]] = function(){};
}
   <!DOCTYPE html>
   <html>
   <head id="mainhead">
   <script src="ks.js" id="ksjs"></script>
   <script src="mainfile.js" id="mainjs"></script>
   <link rel="stylesheet" href="style.css" id="style">
   <meta id="meta1" name="description" content="Proper mitigation against script kiddies via Javascript" >
   </head>
   <body>
   <h1 id="heading" name="dontdel" value="2">Delete this from console and it will refresh. If you change the name attribute in this it will also refresh. This is mitigating an attack on attribute change via console to exploit vulnerabilities. You can even try and change the value attribute from 2 to anything you like. If This script says it is 2 it should be 2 or it will refresh. </h1>
   <h3>Deleting this wont refresh the page due to it having no integrity check on it</h3>

   <p>You can also add this type of error checking on meta tags and add one script out of the head tag to check for changes in the head tag. You can add many js files to ensure an attacker cannot delete all in the second it takes to refresh. Be creative and make this your own as your website needs it. 
   </p>

   <p>This is not the end of it since we can still enter any tag to load anything from everywhere (Dependent on headers etc) but we want to prevent the important ones like an override in meta tags that load headers. The console is designed to edit html but that could add potential html that is dangerous. You should not be able to enter any meta tags into this document unless it is as specified by the ks.js file as permissable. <br>This is not only possible with meta tags but you can do this for important tags like input and script. This is not a replacement for headers!!! Add your headers aswell and protect them with this method.</p>
   </body>
   <script src="ps.js" id="psjs"></script>
   </html>
   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var ksExists = document.getElementById("ksjs"); 
   if(ksExists) {
   }else{ location.reload();};

   var psExists = document.getElementById("psjs");
   if(psExists) {
   }else{ location.reload();};

   var styleExists = document.getElementById("style");
   if(styleExists) {
   }else{ location.reload();};


   }, 1 * 1000); // 1 * 1000 milsec
   /*This script checks if mainjs exists as an element. If main js is not existent as an id in the html file reload!You can add this to all js files to ensure that your page integrity is perfect every second. If the page integrity is bad it reloads the page automatically and the process is restarted. This will blind an attacker as he has one second to disable every javascript file in your system which is impossible.

   */

   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var mainExists = document.getElementById("mainjs"); 
   if(mainExists) {
   }else{ location.reload();};

   //check that heading with id exists and name tag is dontdel.
   var headingExists = document.getElementById("heading"); 
   if(headingExists) {
   }else{ location.reload();};
   var integrityHeading = headingExists.getAttribute('name');
   if(integrityHeading == 'dontdel') {
   }else{ location.reload();};
   var integrity2Heading = headingExists.getAttribute('value');
   if(integrity2Heading == '2') {
   }else{ location.reload();};
   //check that all meta tags stay there
   var meta1Exists = document.getElementById("meta1"); 
   if(meta1Exists) {
   }else{ location.reload();};

   var headExists = document.getElementById("mainhead"); 
   if(headExists) {
   }else{ location.reload();};

   }, 1 * 1000); // 1 * 1000 milsec
   /*This script checks if mainjs exists as an element. If main js is not existent as an id in the html file reload! You can add this to all js files to ensure that your page integrity is perfect every second. If the page integrity is bad it reloads the page automatically and the process is restarted. This will blind an attacker as he has one second to disable every javascript file in your system which is impossible.

   */

   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var mainExists = document.getElementById("mainjs"); 
   if(mainExists) {
   }else{ location.reload();};
   //Check meta tag 1 for content changes. meta1 will always be 0. This you do for each meta on the page to ensure content credibility. No one will change a meta and get away with it. Addition of a meta in spot 10, say a meta after the id="meta10" should also be covered as below.
   var x = document.getElementsByTagName("meta")[0];
   var p = x.getAttribute("name");
   var s = x.getAttribute("content");
   if (p != 'description') {
   location.reload();
   }
   if ( s != 'Proper mitigation against script kiddies via Javascript') {
   location.reload();
   }
   // This will prevent a meta tag after this meta tag @ id="meta1". This prevents new meta tags from being added to your pages. This can be used for scripts or any tag you feel is needed to do integrity check on like inputs and scripts. (Yet again. It is not a replacement for headers to be added. Add your headers aswell!)
   var lastMeta = document.getElementsByTagName("meta")[1];
   if (lastMeta) {
   location.reload();
   }
   }, 1 * 1000); // 1 * 1000 milsec
   #heading {
   background-color:red;
   }
setInterval(()=>console.clear(),1500);
Object.defineProperty(window, 'console', {
  get: function() {

  },
  set: function() {

  }
});
function isConsoleOpen(){
if((window.outerWidth - window.innerWidth)>100){return true;}
if((navigator.platform=="Win32")&&(navigator.userAgent.indexOf("Windows ")==-1)){return true;}else{return false;}}
if (document.hasFocus()) {...}