etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2022. 1. 5. 09:43
반응형

질문자 :Derek 朕會功夫


따라서 최근 사기로 인해 사람들이 개발자 도구를 악용하여 스팸을 게시하고 계정을 "해킹"하기까지 합니다. 페이스북이 개발자 도구를 차단해서 콘솔도 못씁니다.

여기에 이미지 설명 입력

그들은 어떻게 그것을 했는가?? 한 스택 오버플로 게시물은 불가능하다고 주장 했지만 페이스북은 그것들이 틀렸다는 것을 증명했습니다.

Facebook으로 이동하여 개발자 도구를 열고 콘솔에 한 문자를 입력하면 이 경고가 나타납니다. 무엇을 넣어도 실행되지 않습니다.

이것이 어떻게 가능한지?

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

여기에 이미지 설명 입력



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

분명히 하자면 클라이언트 측에서 해커를 차단하려는 것은 일반적으로 나쁜 생각입니다. 이것은 특정 사회 공학적 공격 으로부터 보호하기 위한 것입니다.

테스트 그룹에 포함되어 이로 인해 짜증이 난다면 죄송합니다. 나는 이전 옵트 아웃 페이지 (지금 만들려고 도움말 페이지를 여전히 정지 피해자의 적어도 일부를 무서운 충분히하면서 가능한 한 간단하게).

실제 코드는 @joeldixon66의 링크 와 매우 유사합니다. 우리는 정당한 이유없이 조금 더 복잡합니다.

Chrome은 모든 콘솔 코드를 다음으로 래핑합니다.

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

... 따라서 사이트는 다음을 던지 console._commandLineAPI

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

이것은 충분하지 않지만(시도해보세요!) , 이것이 주요 트릭입니다.


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


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

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

참조:


Salman A

나는 그것을 어떤 페이지에서도 실행할 수 없었다. 이것의 더 강력한 버전은 다음을 수행합니다.

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

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

Edit Thinking @joeldixon66 의 올바른 아이디어: 콘솔에서 JavaScript 실행 비활성화 « ::: KSpace :::


Will

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

편집하다:

Chrome은 이전 릴리스에서 이 문제를 수정했습니다. - 2015년 2월 이전에 작성했을 것입니다. 당시 요지를 작성했기 때문에

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

InjectedScript._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. eg; //{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._evaluateAndWrap 바로 그 식을 평가, 다음과 같은 출력을 제공합니다 :

여기에 이미지 설명 입력

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

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

is - InjectedScriptHost - 개체를 살펴보십시오. 이것은 인스펙터의 내부에 대해 약간의 통찰력을 얻고 가지고 놀 수 있는 몇 가지 방법을 제공합니다.

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

else 경로의 return 문을 return res 다음 console.log (res) 로 바꾸면 됩니다. 그러면 다음과 같이 끝납니다.

여기에 이미지 설명 입력

편집 끝


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

Function.prototype.call 연결하는 것입니다.

InjectedScriptHost thisArg 로 사용하여 평가 함수를 call 하여 입력된 표현식을 평가합니다.


Community Wiki

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


Fizer Khan

이것은 페이스북이 할 수 있었기 때문에 실제로 가능했습니다. 글쎄, 실제 웹 개발자 도구가 아니라 콘솔에서 Javascript를 실행하는 것입니다.

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

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

클라이언트 측이라고 하면 서버의 제어 외부에서 발생하므로 이에 대해 할 수 있는 일은 많지 않습니다. Facebook이 여전히 이 작업을 수행하는 이유를 묻는다면 이것은 보안을 위한 것이 아니라 javascript를 모르는 일반 사용자가 콘솔에서 코드(읽는 방법을 모르는)를 실행하지 못하도록 보호하기 위한 것입니다. 이는 요청한 작업을 수행한 후 자동 좋아하는 서비스 또는 기타 Facebook 기능 봇을 약속하는 사이트에서 일반적입니다. 대부분의 경우 콘솔에서 실행할 자바스크립트 조각을 제공합니다.

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

콘솔에서 자바스크립트를 비활성화하더라도 주소 표시줄을 통해 자바스크립트를 실행하는 것은 여전히 가능합니다.

여기에 이미지 설명 입력

여기에 이미지 설명 입력

브라우저가 주소 표시줄에서 javascript를 비활성화하는 경우(Google 크롬의 주소 표시줄에 코드를 붙여넣으면 'javascript:' 구문이 삭제됨) inspect 요소를 통해 링크 중 하나에 javascript를 붙여넣는 것은 여전히 가능합니다.

앵커 검사:

여기에 이미지 설명 입력

href에 코드 붙여넣기:

여기에 이미지 설명 입력

여기에 이미지 설명 입력

여기에 이미지 설명 입력

결론은 서버 측 유효성 검사이며 보안이 먼저 되어야 하고 그 다음에 클라이언트 측을 수행해야 한다는 것입니다.


Jomar Sevillejo

Facebook이 콘솔을 비활성화할 수 있었던 이후로 Chrome이 많이 변경되었습니다...

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

Alpha2k

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

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

Dusan Krstic

getCompletions 라는 IIFE를 주입하며, Devtools 콘솔 내부에서 키를 누를 때 호출됩니다.

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

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


Sam Denty

간단한 솔루션!

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

Mohmmad Ebrahimi Aval

나는 다음과 같은 길을 갈 것이다:

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

Zibri

페이스북 이러지마!!

안녕하세요 여러분, 주의하십시오. Facebook Dont do this
이것은 고객을 놀라게 하려는 가짜 전략일 뿐입니다.

이 코드는 기본적으로 페이지 로드 시 콘솔에 작성합니다. 콘솔을 열거나 열지 않으면 빨간색 'STOP' 단어가 표시됩니다... :)

그들은 단지 콘솔 기능을 다시 작성하고 콘솔을 열고 모두 다시 작성할 수 있습니다 :|
경고 기능이나 다른 모든 js 기능이 여전히 잘 작동하기 때문입니다.

다음 코드를 통해 별도의 개발자 도구가 열리지 않는 것을 감지할 수 있습니다.

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

별도의 개발자 도구 열림 감지용
window.blur에서 활성화된 전략이 있어야 하고 (간격으로 서버에서 데이터를 로드하는 함수 외...) 호출된 함수가 있는지 확인하면 알고리즘이 클라이언트가 별도의 개발 도구에서 작동하고 있음을 감지할 수 있습니다.

간단한 해결책: 이 코드를 ur 주요 js 기능에 추가하십시오.

 if (document.hasFocus()) {...}

하드 솔루션:
ur 코드의 모든 js 기능에 추가 코드 스니펫 추가


Eyni Kave

이것은 약한 코드가 방치되는 보안 조치가 아닙니다. 이 전략을 구현하기 전에 항상 취약한 코드에 대한 영구적인 솔루션을 확보하고 웹사이트를 적절하게 보호하십시오.

내 지식에 따르면 지금까지 가장 좋은 도구는 콘텐츠를 새로 고치거나 교체하여 페이지의 무결성을 다시 정상으로 변경하는 여러 자바스크립트 파일을 추가하는 것입니다. 이 개발자 도구를 비활성화하는 것은 코드가 서버 렌더링이 아니라 브라우저의 일부이므로 크랙될 수 있으므로 우회가 항상 문제가 되기 때문에 가장 좋은 아이디어는 아닙니다.

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>

메인파일.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

스타일.css

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

 #heading { background-color:red; }

이 모든 파일을 함께 넣고 예제를 빌드하면 이 측정의 기능을 볼 수 있습니다. 이것은 특히 PHP로 작업할 때 인덱스 파일의 모든 중요한 요소에 올바르게 구현해야 예상치 못한 주입을 방지할 수 있습니다.

속성당 일반 값으로 다시 변경하는 대신 다시 로드를 선택한 이유는 일부 공격자가 웹 사이트의 다른 부분을 이미 구성하고 준비할 수 있고 코드 양을 줄일 수 있다는 사실입니다. 재장전은 공격자의 모든 노력을 제거하고 아마도 더 쉬운 곳으로 갈 것입니다.

또 다른 참고 사항: 이것은 많은 코드가 될 수 있으므로 깨끗하게 유지하고 나중에 쉽게 편집할 수 있도록 해당 위치에 정의를 추가해야 합니다. 또한 큰 페이지에서 1초 간격은 방문자가 사용하는 구형 컴퓨터에 큰 영향을 미칠 수 있으므로 원하는 양으로 초를 설정하십시오.


user9374996

출처 : http:www.stackoverflow.com/questions/21692646/how-does-facebook-disable-the-browsers-integrated-developer-tools

반응형