it-swarm-ko.com

Facebook은 브라우저의 통합 개발자 도구를 어떻게 비활성화합니까?

따라서 최근의 사기로 인해 개발자 도구는 사람들이 스팸을 게시하고 심지어 계정을 "해킹"하는 데 악용되었습니다. Facebook은 개발자 도구를 차단했으며 콘솔을 사용할 수도 없습니다.

Enter image description here

그들은 어떻게 그랬습니까 ?? 한 스택 오버 플로우 게시물은 불가능하다고 주장했습니다 하지만 페이스 북은 틀린 것으로 입증되었습니다.

Facebook에 가서 개발자 도구를 열고 콘솔에 한 글자를 입력하면이 경고가 나타납니다. 당신이 무엇을 넣든 상관없이, 그것은 처형되지 않을 것입니다.

이것이 어떻게 가능한지?

심지어 콘솔에서 자동 완성을 차단했습니다.

Enter image description here

1617
Derek 朕會功夫

나는 페이스 북의 보안 엔지니어이고 이것이 내 잘못이다. 우리는 사용자가 (악의적 인) JavaScript 코드를 브라우저 콘솔에 붙여 넣도록 속이는 공격을 느리게 할 수 있는지 확인하기 위해 일부 사용자에 대해 이것을 테스트하고 있습니다.

해커를 클라이언트 측에서 차단하려고하는 것은 일반적으로 나쁜 생각 입니다. 이것은 특정 사회 공학 공격 을 막기위한 것입니다.

테스트 그룹에 들어가서 이것에 대해 화가났다면 죄송합니다. 이전 옵트 아웃 페이지 (현재 도움말 페이지 )를 최대한 간단하게 만들려고 시도했지만 적어도 some 피해자.

실제 코드는 @ joeldixon66의 링크 ; 우리는 아무 이유없이 조금 더 복잡합니다.

Chrome은 모든 콘솔 코드를

with ((console && console._commandLineAPI) || {}) {
  <code goes here>
}

... 사이트에서 console._commandLineAPI을 (를) 재정의합니다.

Object.defineProperty(console, '_commandLineAPI',
   { get : function() { throw 'Nooo!' } })

이것은 충분하지 않습니다 (시도해주세요!) 이지만 이것이 주요 요령입니다.


Epilogue : Chrome 팀은 사용자 측 JS에서 콘솔을 물리 치는 것이 버그이며 문제 수정 라고 판단하여이 기술을 무효화했습니다. 그 후 self-xss로부터 사용자를 보호 에 추가 보호 기능이 추가되었습니다.

2384
Alf

Chrome 개발자 도구를 사용하여 Facebook의 콘솔 버스터 스크립트를 배치했습니다. 다음은 가독성을위한 사소한 변경 사항이있는 스크립트입니다. 나는 이해할 수없는 것들을 제거했다.

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);

이렇게하면 콘솔에 입력 된 명령문이 실행되지 않으면 콘솔 자동 완성이 자동으로 실패합니다 (예외가 기록됨).

참고 문헌 :

78
Salman A

나는 그것을 어떤 페이지에서라도 발동시키지 못했습니다. 이것의 더 견고한 버전은 그것을 할 것입니다 :

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

console.log('test');

출력 스타일 지정 : JavaScript 콘솔의 색상

편집 생각 @ joeldixon66 올바른 생각을 가지고 : 콘솔에서 JavaScript 실행을 비활성화«: KSpace ::: -

38
Will

console._commandLineAPI 재정의 외에도 WebKit 브라우저에서 InjectedScriptHost에 침입하여 개발자 콘솔에 입력 된 표현식의 평가를 방지하거나 변경하는 다른 방법이 있습니다.

편집 :

Chrome은 지난 릴리스에서이 문제를 해결했습니다. -그 당시 Gist를 만들었으므로 2015 년 2 월 이전에 있었어야합니다

여기 또 다른 가능성이 있습니다. 이번에는 이전 버전과 달리 InjectedScript이 아닌 InjectedScriptHost에 직접 레벨을 연결합니다.

InjectedScript._evaluateAndWrap에 의존하지 않고 InjectedScriptHost.evaluate 원숭이 패치를 직접 수행 할 수 있기 때문에 어떤 일이 발생해야 하는지를보다 세밀하게 제어 할 수 있으므로 Nice의 일종입니다.

또 다른 흥미로운 점은 표현식이 평가 될 때 내부 결과를 가로 챌 수 있으며 정상적인 동작 대신 사용자에게 return that .

다음은 사용자가 콘솔에서 무언가를 평가할 때 내부 결과를 반환하는 코드입니다.

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]을 평가하면 다음과 같은 결과가 나타납니다.

enter image description here

InjectedScript._evaluateAndWrap와 동일한 표현식을 원숭이 패치 한 후 다음과 같은 결과가 나타납니다.

enter image description here

보시다시피 출력을 나타내는 작은 왼쪽 화살표가 여전히 있지만 이번에는 객체를 얻습니다. 식의 결과에서 [1,2,3,4] 배열은 설명 된 모든 속성을 가진 개체로 표시됩니다.

오류를 생성하는 표현식을 포함하여이 표현식과 해당 표현식을 평가하는 것이 좋습니다. 꽤 흥미 롭습니다.

또한 is-InjectedScriptHost- 개체를 살펴보십시오. 인스펙터의 내부를 가지고 약간의 통찰력을 얻는 방법을 제공합니다.

물론 모든 정보를 가로 채어 원래 결과를 사용자에게 반환 할 수 있습니다.

Else 경로의 return 문을 return res 다음에 오는 console.log (res)로 바꾸십시오. 그런 다음 다음과 같이 끝납니다.

enter image description here

편집 끝


이것은 Google에서 수정 한 이전 버전입니다. 따라서 더 이상 가능한 방법은 아닙니다.

그 중 하나가 Function.prototype.call에 연결되어 있습니다.

Chrome은 callInjectedScriptHost로 사용하여 eval 함수를 thisArging하여 입력 된 표현식을 평가합니다.

var result = evalFunction.call(object, expression);

이 경우 thisArgcall을 (를) evaluate 수신하고 첫 번째 인수 (InjectedScriptHost)에 대한 참조를 얻을 수 있습니다.

if (window.URL) {
    var ish, _call = Function.prototype.call;
    Function.prototype.call = function () { //Could be wrapped in a setter for _commandLineAPI, to redefine only when the user started typing.
        if (arguments.length > 0 && this.name === "evaluate" && arguments [0].constructor.name === "InjectedScriptHost") { //If thisArg is the evaluate function and the arg0 is the ISH
            ish = arguments[0];
            ish.evaluate = function (e) { //Redefine the evaluation behaviour
                throw new Error ('Rejected evaluation of: \n\'' + e.split ('\n').slice(1,-1).join ("\n") + '\'');
            };
            Function.prototype.call = _call; //Reset the Function.prototype.call
            return _call.apply(this, arguments);  
        }
    };
}

예를 들어 평가가 거부되었다는 오류가 발생합니다.

enter image description here

여기에 입력 된 표현식이 evaluate 함수로 전달되기 전에 CoffeeScript 컴파일러로 전달되는 example 이 있습니다.

28
Moritz Roessler

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$$) {
    }
})();

보안 오류를 발생시키기 위해 console._commandLineAPI를 무시합니다.

22
Fizer Khan

Facebook이 그것을 할 수 있었기 때문에 실제로 가능합니다. 실제 웹 개발자 도구가 아니라 콘솔에서 Javascript를 실행합니다.

다음을보십시오 : Facebook은 브라우저의 통합 개발자 도구를 어떻게 비활성화합니까?

이 유형의 클라이언트 측 보안을 우회하는 다른 방법이 있기 때문에 이것은 실제로는별로 도움이되지 않습니다.

클라이언트 쪽이라면 서버 제어권 밖에서 발생하기 때문에 할 수있는 일이 많지 않습니다. 페이스 북이 아직도 이것을하는 이유를 묻는다면 이것은 보안을위한 것이 아니라 자바 스크립트를 모르는 일반 사용자가 코드를 실행하는 것을 (그들이 읽는 법을 모르는) 콘솔에 보호하는 것이다. 이것은 자동 실행 서비스 또는 다른 Facebook 기능 봇을 약속 한 사이트에서 일반적으로 수행하는 작업입니다. 대부분의 경우 콘솔에서 실행되는 javascript를 제공합니다.

Facebook만큼 많은 사용자가 없다면 Facebook이하는 일을 할 필요가 없다고 생각합니다.

콘솔에서 Javascript를 사용 중지하더라도 주소 표시 줄을 통해 javascript를 실행할 수 있습니다.

 enter image description here

 enter image description here

그리고 브라우저가 주소 표시 줄에서 자바 스크립트를 비활성화하면 (Google 크롬의 주소 표시 줄에 코드를 붙여 넣으면 'javascript :'라는 문구가 삭제됩니다.) javascript를 inspect 요소를 통해 링크 중 하나로 붙여 넣을 수도 있습니다.

앵커를 검사합니다 :

 enter image description here

href에 코드 붙여 넣기 :

 enter image description here

 enter image description here

 enter image description here

결론은 서버 측 유효성 검사이며 보안이 먼저 있어야하고 클라이언트 측이 수행해야합니다.

20
Jomar Sevillejo

페이스 북이 콘솔을 사용하지 못하게 할 수 있기 때문에 크롬이 많이 바뀌 었습니다 ... 

2017 년 3 월 현재 더 이상 작동하지 않습니다. 

콘솔 기능 중 일부를 사용하지 않도록 설정할 수 있습니다 (예 :

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(){};
}
7
Alpha2k

내 간단한 방법이지만이 주제에 대한 추가 변형을 도울 수 있습니다. 모든 방법을 나열하고 쓸모없는 것으로 변경하십시오.

  Object.getOwnPropertyNames(console).filter(function(property) {
     return typeof console[property] == 'function';
  }).forEach(function (verb) {
     console[verb] =function(){return 'Sorry, for security reasons...';};
  });
6
Dusan Krstic

Devtools 콘솔에서 키를 누르면 내부적으로 devtools가 getCompletions이라는 IIFE를 페이지에 삽입합니다. 

함수의 소스 를 보면 덮어 쓸 수있는 몇 가지 전역 함수를 사용합니다.

Error 생성자를 사용하면 호출 스택을 가져올 수 있습니다.이 스택에는 Devtools에서 호출 할 때 getCompletions이 포함됩니다.


예 :

const disableDevtools = callback => {
  const original = Object.getPrototypeOf;

  Object.getPrototypeOf = (...args) => {
    if (Error().stack.includes("getCompletions")) callback();
    return original(...args);
  };
};

disableDevtools(() => {
  console.error("devtools has been disabled");

  while (1);
});

3
samdd

간단한 해결책!

setInterval(()=>console.clear(),1500);
2

나는 길을 따라 갈 것이다 :

Object.defineProperty(window, 'console', {
  get: function() {

  },
  set: function() {

  }
});
0
Zibri

약한 코드가 무인 상태로 유지되는 보안 조치는 아닙니다. 이 전략을 구현하기 전에 항상 약한 코드에 대한 영구 솔루션을 얻고 웹 사이트를 안전하게 보호하십시오.

내 지식에 따르면 지금까지 가장 좋은 도구는 콘텐츠를 새로 고치거나 바꾸어 페이지의 무결성을 단순히 정상으로 변경하는 여러 자바 스크립트 파일을 추가하는 것입니다. 바이 패싱은 항상 문제가되기 때문에이 코드를 사용하지 않는 것이 가장 좋은 아이디어는 아닙니다. 코드가 서버 렌더링이 아닌 브라우저의 일부이므로 균열이 발생할 수 있습니다. 

중요 요소에 대해 js file one<element> 변경 사항을 확인하고 js file twojs file three 기간 동안이 파일이 있는지 확인해야합니다. 그러면 해당 기간 내에 페이지에서 완전 무결성 복원을 수행하게됩니다. 

4 개의 파일을 예로 들어 보자. 

index.html

   <!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>

mainfile.js

   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

ps.js

   /*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

ks.js

   /*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

style.css

이제 이것은 모든 파일과 태그에서도 작동한다는 것을 보여줍니다.

   #heading {
   background-color:red;
   }

이 파일들을 모아서 예제를 만들면이 측정의 기능을 볼 수 있습니다. 이렇게하면 특히 PHP로 작업 할 때 색인 파일의 모든 중요한 요소에 올바르게 구현해야하는 유출을 예방할 수 있습니다.

속성 대신 정상 값으로 변경하는 대신 재로드를 선택하는 이유는 일부 공격자가 웹 사이트의 다른 부분을 이미 구성하고 준비 할 수 있고 코드 금액을 줄일 수 있다는 사실입니다. 다시로드하면 공격자의 모든 노력이 제거되며 어딘가에서 쉽게 플레이 할 수 있습니다.

또 다른 메모 : 이것은 많은 코드가 될 수 있으므로 깨끗하게 유지하고 나중에 어디에서 편집을 쉽게 할 수 있도록 정의를 추가하는지 확인하십시오. 또한 큰 페이지에서 1 초 간격으로 방문자가 사용중인 오래된 컴퓨터에 큰 영향을 미칠 수 있으므로 원하는 시간 (초)을 설정하십시오.

0
user9374996