Vraag Hoe schakelt Facebook de geïntegreerde ontwikkelaarstools van de browser uit?


Dus blijkbaar vanwege de recente zwendel, worden de ontwikkelaarstools uitgebuit door mensen om spam te posten en zelfs gebruikt om accounts te "hacken". Facebook heeft de ontwikkelaarstools geblokkeerd en ik kan de console zelfs niet gebruiken.

Enter image description here

Hoe deden ze dat ?? Eén Stack Overflow-post beweerde dat dit niet mogelijk was, maar Facebook heeft bewezen dat ze het bij het verkeerde eind hebben.

Ga gewoon naar Facebook en open de ontwikkelaarstools, typ een personage in de console en deze waarschuwing verschijnt. Het maakt niet uit wat je erin stopt, het wordt niet uitgevoerd.

Hoe is dit mogelijk?

Ze hebben zelfs automatisch aanvullen in de console geblokkeerd:

Enter image description here


1560
2018-02-11 03:42


oorsprong


antwoorden:


Ik ben een beveiligingsingenieur bij Facebook en dit is mijn schuld. We testen dit voor sommige gebruikers om te zien of het enkele aanvallen kan vertragen waarbij gebruikers ertoe worden aangezet om (kwaadwillende) JavaScript-code in de browserconsole te plakken.

Voor alle duidelijkheid: een poging om hackers te blokkeren, is een slecht idee in het algemeen; dit is om te beschermen tegen een specifieke social engineering aanval.

Als je in de testgroep terecht bent gekomen en je geïrriteerd bent, sorry. Ik heb geprobeerd de oude opt-outpagina te maken (nu help-pagina) zo eenvoudig mogelijk terwijl je nog steeds eng genoeg bent om op zijn minst te stoppen sommige van de slachtoffers.

De eigenlijke code lijkt veel op @ joeldixon66's link; de onze is iets gecompliceerder zonder goede reden.

Chrome verpakt alle console-code in

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

... dus de site herdefinieert console._commandLineAPI gooien:

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

Dit is niet helemaal genoeg (probeer het maar!), maar dat is het hoofdtruc.


Nawoord: het Chrome-team heeft besloten dat het verslaan van de console van gebruikers-JS een bug was en het probleem verholpen, waardoor deze techniek ongeldig wordt. Nadien is extra bescherming toegevoegd aan gebruikers beschermen tegen self-xss.


2281
2018-02-11 05:33



Ik heb het console-buster-script van Facebook gevonden met behulp van Chrome-ontwikkelaarstools. Hier is het script met kleine wijzigingen voor de leesbaarheid. Ik heb de stukjes verwijderd die ik niet kon begrijpen:

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

Hiermee mislukt het automatisch voltooien van de console, terwijl instructies die in de console zijn ingevoerd, niet kunnen worden uitgevoerd (de uitzondering wordt vastgelegd).

Referenties:


72
2018-02-15 08:16



Ik kon het niet krijgen om dat op een willekeurige pagina te activeren. Een robuustere versie hiervan zou het doen:

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

console.log('test');

Om de output te stylen: Kleuren in JavaScript-console

Bewerk het denken @ joeldixon66 heeft het juiste idee: Uitschakelen van JavaScript-uitvoering van console «::: KSpace :::


36
2018-02-11 04:02



Naast het opnieuw definiëren console._commandLineAPI, er zijn een aantal andere manieren om in te breken in InjectedScriptHost in WebKit-browsers om de evaluatie van expressies die zijn ingevoerd in de ontwikkelaarsconsole te voorkomen of te wijzigen.

Bewerk:

Chrome heeft dit in een eerdere versie opgelost. - dat moet vóór februari 2015 zijn geweest, toen ik de essentie op dat moment creëerde 

Dus hier is nog een mogelijkheid. Deze keer haken we een niveau erboven direct in InjectedScript liever dan InjectedScriptHost in tegenstelling tot de vorige versie.

Dat is best leuk, want je kunt direct een aapjeslapje maken InjectedScript._evaluateAndWrap in plaats van erop te vertrouwen InjectedScriptHost.evaluate omdat dat je meer fijnmazige controle geeft over wat er zou moeten gebeuren.

Een ander interessant ding is dat we het interne resultaat kunnen onderscheppen als een uitdrukking wordt geëvalueerd en keer dat terug voor de gebruiker in plaats van het normale gedrag.

Hier is de code, die precies dat doet, het interne resultaat retourneren wanneer een gebruiker iets in de console evalueert.

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

Het is een beetje uitgebreid, maar ik dacht dat ik er wat opmerkingen in zou plaatsen

Dus normaal, als een gebruiker bijvoorbeeld evalueert [1,2,3,4] je zou de volgende output verwachten:

enter image description here 

Na monkeypatching InjectedScript._evaluateAndWrap evalueren van dezelfde expressie, geeft de volgende uitvoer:

enter image description here

Zoals je ziet is de pijl-links, die de uitvoer aangeeft, er nog steeds, maar deze keer krijgen we een object. Waar het resultaat van de uitdrukking de array is [1,2,3,4] wordt voorgesteld als een object met alle beschreven eigenschappen.

Ik raad aan om deze en die expressie te evalueren, inclusief die welke fouten genereren. Het is best interessant.

Bekijk ook de is  - InjectedScriptHost - voorwerp. Het biedt enkele methoden om mee te spelen en een beetje inzicht te krijgen in de binnenkant van de inspecteur.

Natuurlijk kunt u al die informatie onderscheppen en nog steeds het oorspronkelijke resultaat aan de gebruiker teruggeven.

Vervang de return-instructie in het else-pad door een console.log (res) volgende a return res. Dan zou je eindigen met het volgende.

enter image description here 

Einde van bewerking 


Dit is de vorige versie die door Google is opgelost. Vandaar geen manier meer.

Een daarvan is inhaken Function.prototype.call

Chrome evalueert de ingevoerde expressie met callzijn eval functie met InjectedScriptHost als thisArg


25
2018-02-19 14:49



Netflix implementeert deze functie ook

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

Ze overschrijven gewoon console._commandLineAPI om een ​​beveiligingsfout te maken.


19
2018-03-06 06:20



Dit is eigenlijk mogelijk sinds Facebook in staat was om het te doen. Nou, niet de eigenlijke webontwikkelaarstools, maar de uitvoering van Javascript in console.

Zie dit: Hoe schakelt Facebook de geïntegreerde ontwikkelaarstools van de browser uit?

Dit zal echt niet veel doen, omdat er andere manieren zijn om dit type client-side beveiliging te omzeilen.

Wanneer u zegt dat het client-side is, gebeurt dit buiten de controle van de server, dus u kunt er niet veel aan doen. Als je je afvraagt ​​waarom Facebook dit nog steeds doet, is dit niet echt voor de beveiliging, maar om normale gebruikers die javascript niet weten te beschermen tegen het uitvoeren van code (die ze niet kunnen lezen) in de console. Dit is gebruikelijk voor sites die auto-likerservice of andere bots met Facebook-functionaliteit beloven nadat je hebt gedaan wat ze je vragen te doen, waar ze in de meeste gevallen een knip JavaScript geven om in de console te worden uitgevoerd.

Als je niet zoveel gebruikers als Facebook hebt, denk ik niet dat het nodig is om te doen wat Facebook aan het doen is.

Zelfs als u Javascript in console uitschakelt, is het uitvoeren van javascript via de adresbalk nog steeds mogelijk.

enter image description here

enter image description here

en als de browser javascript op de adresbalk uitschakelt (als u de code in de adresbalk in Google Chrome plakt, wordt de zinsnede 'javascript:' verwijderd) is het javascript plakken in een van de koppelingen via het inspectie-element nog steeds mogelijk.

Inspecteer het anker:

enter image description here

Plak de code in href:

enter image description here

enter image description here

enter image description here

De bottom line is de validering aan de serverzijde en de beveiliging moet eerst zijn en daarna de client-side.


18
2017-11-05 00:57



Chrome is veel veranderd sinds de tijd dat Facebook de console kon uitschakelen ...

Vanaf maart 2017 werkt dit niet meer.

Het beste wat je kunt doen is een aantal consolefuncties uitschakelen, bijvoorbeeld:

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

5
2018-03-12 12:44



Mijn eenvoudige manier, maar het kan helpen bij verdere variaties op dit onderwerp. Maak een lijst van alle methoden en verander ze naar nutteloos.

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

3
2017-11-18 22:29