Question Comment Facebook désactive-t-il les outils de développement intégrés du navigateur?


Donc, apparemment à cause des escroqueries récentes, les outils de développement sont exploités par des gens pour poster des spams et même utilisés pour "pirater" des comptes. Facebook a bloqué les outils de développement, et je ne peux même pas utiliser la console.

Enter image description here

Comment ont-ils fait ça? Une publication de Stack Overflow prétendait que ce n'était pas possible, mais Facebook leur a prouvé qu'ils avaient tort.

Il suffit d'aller sur Facebook et ouvrez les outils de développement, tapez un caractère dans la console, et cet avertissement apparaît. Peu importe ce que vous mettez, il ne sera pas exécuté.

Comment est-ce possible?

Ils ont même bloqué l'auto-complétion dans la console:

Enter image description here


1560
2018-02-11 03:42


origine


Réponses:


Je suis un ingénieur de sécurité chez Facebook et c'est de ma faute. Nous testons cela pour certains utilisateurs pour voir si cela peut ralentir certaines attaques où les utilisateurs sont amenés à coller du code JavaScript (malveillant) dans la console du navigateur.

Juste pour être clair: essayer de bloquer les pirates côté client est un mauvaise idée en général; c'est pour se protéger contre un attaque d'ingénierie sociale spécifique.

Si vous avez fini dans le groupe de test et êtes ennuyé par cela, désolé. J'ai essayé de faire la vieille page de désabonnement (maintenant page d'aide) aussi simple que possible tout en étant assez effrayant pour arrêter au moins certains des victimes.

Le code actuel est assez similaire à Le lien de @ joeldixon66; le nôtre est un peu plus compliqué sans raison valable.

Chrome enveloppe tout le code de la console

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

... donc le site redéfinit console._commandLineAPI lancer:

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

C'est pas assez (essayez-le!)mais c'est le astuce principale.


Épilogue: L'équipe Chrome a décidé que la défaite de la console à partir de JS côté utilisateur était un bug et résolu le problème, rendant cette technique invalide. Ensuite, une protection supplémentaire a été ajoutée à protéger les utilisateurs de self-xss.


2281
2018-02-11 05:33



J'ai localisé le script Buster de la console de Facebook à l'aide des outils de développement Chrome. Voici le script avec des changements mineurs pour la lisibilité. J'ai enlevé les bits que je ne pouvais pas comprendre:

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

Avec cela, la console auto-complète échoue silencieusement tandis que les instructions tapées dans la console échoueront à s'exécuter (l'exception sera enregistrée).

Les références:


72
2018-02-15 08:16



Je ne pouvais pas l'obtenir pour déclencher cela sur n'importe quelle page. Une version plus robuste de cela le ferait:

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

console.log('test');

Pour styliser la sortie: Couleurs dans la console JavaScript

modifier En pensant @ joeldixon66 a la bonne idée: Désactiver l'exécution JavaScript depuis la console «::: KSpace :::


36
2018-02-11 04:02



En plus de redéfinir console._commandLineAPI, Il existe d'autres façons de pénétrer InjectedScriptHost sur les navigateurs WebKit, pour empêcher ou modifier l'évaluation des expressions entrées dans la console du développeur.

Modifier:

Chrome a résolu cela dans une version antérieure. - qui doit avoir été avant Février 2015, comme j'ai créé l'essentiel à ce moment-là 

Alors, voici une autre possibilité. Cette fois, nous nous accrochons, un niveau ci-dessus, directement dans InjectedScript plutôt que InjectedScriptHost par opposition à la version précédente.

Ce qui est gentil, comme vous pouvez directement patch de singe InjectedScript._evaluateAndWrap au lieu d'avoir à compter sur InjectedScriptHost.evaluate car cela vous donne un contrôle plus précis sur ce qui devrait arriver.

Une autre chose intéressante est que nous pouvons intercepter le résultat interne lorsqu'une expression est évaluée et retourne ça à l'utilisateur au lieu du comportement normal.

Voici le code, qui fait exactement cela, renvoie le résultat interne lorsqu'un utilisateur évalue quelque chose dans la console.

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

C'est un peu bavard, mais je pensais y mettre quelques commentaires

Donc normalement, si un utilisateur, par exemple, évalue [1,2,3,4] vous attendez la sortie suivante:

enter image description here 

Après monkeypatching InjectedScript._evaluateAndWrap évaluer la même expression, donne la sortie suivante:

enter image description here

Comme vous voyez la petite flèche gauche, indiquant la sortie, est toujours là, mais cette fois nous obtenons un objet. Où le résultat de l'expression, le tableau [1,2,3,4] est représenté comme un objet avec toutes ses propriétés décrites.

Je recommande d'essayer d'évaluer ceci et cette expression, y compris celles qui génèrent des erreurs. C'est très intéressant.

De plus, jetez un oeil à la is  - InjectedScriptHost - objet. Il fournit quelques méthodes pour jouer avec et obtenir un peu de perspicacité dans les internes de l'inspecteur.

Bien sûr, vous pouvez intercepter toutes ces informations et retourner le résultat original à l'utilisateur.

Remplacez simplement l'instruction return dans le chemin else par un console.log (res) suite à return res. Ensuite, vous finiriez avec ce qui suit.

enter image description here 

Fin de l'édition 


Ceci est la version antérieure qui a été fixée par Google. Donc plus possible.

L'un d'entre eux est l'accrochage Function.prototype.call

Chrome évalue l'expression entrée par callsa fonction eval avec InjectedScriptHost comme thisArg


25
2018-02-19 14:49



Netflix implémente également cette fonctionnalité

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

Ils remplacent juste console._commandLineAPI pour lancer une erreur de sécurité.


19
2018-03-06 06:20



C'est en fait possible puisque Facebook était capable de le faire. Eh bien, pas les outils de développement Web réels, mais l'exécution de Javascript dans la console.

Regarde ça: Comment Facebook désactive-t-il les outils de développement intégrés du navigateur?

Cela ne fera pas grand chose car il existe d'autres façons de contourner ce type de sécurité côté client.

Quand vous dites que c'est côté client, cela arrive en dehors du contrôle du serveur, donc vous ne pouvez pas faire grand-chose à ce sujet. Si vous demandez pourquoi Facebook fait toujours cela, ce n'est pas vraiment pour la sécurité mais pour protéger les utilisateurs normaux qui ne connaissent pas javascript du code courant (qu'ils ne savent pas lire) dans la console. Ceci est fréquent pour les sites qui promettent un service d'auto-liker ou d'autres robots de fonctionnalité Facebook après que vous fassiez ce qu'ils vous demandent de faire, où dans la plupart des cas, ils vous donnent un coup de javascript pour fonctionner dans la console.

Si vous n'avez pas autant d'utilisateurs que Facebook, je ne pense pas qu'il soit nécessaire de faire ce que fait Facebook.

Même si vous désactivez Javascript dans la console, l'exécution de javascript via la barre d'adresse est toujours possible.

enter image description here

enter image description here

et si le navigateur désactive javascript à la barre d'adresse, (Lorsque vous collez du code dans la barre d'adresse dans Google Chrome, il supprime l'expression 'javascript:') coller javascript dans l'un des liens via l'élément d'inspection est toujours possible.

Inspectez l'ancre:

enter image description here

Coller le code dans href:

enter image description here

enter image description here

enter image description here

Bottom line est la validation côté serveur et la sécurité devrait être d'abord, puis faire côté client après.


18
2017-11-05 00:57



Chrome a beaucoup changé depuis le temps facebook pourrait désactiver la console ...

En mars 2017 cela ne marche plus.

Le mieux que vous pouvez faire est de désactiver certaines fonctions de la console, par exemple:

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



Ma manière simple, mais il peut aider pour d'autres variations sur ce sujet. Liste toutes les méthodes et les modifier à inutiles.

  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



Ce n'est pas une mesure de sécurité pour que le code faible soit laissé sans surveillance. Toujours obtenir une solution permanente à un code faible et sécuriser correctement vos sites Web avant de mettre en œuvre cette stratégie

Le meilleur outil de loin selon mes connaissances serait d'ajouter plusieurs fichiers javascript qui ne font que changer l'intégrité de la page à nouveau en rafraîchissant ou en remplaçant le contenu. La désactivation de cet outil de développement ne serait pas la meilleure idée puisque contournement est toujours en question puisque le code fait partie du navigateur et non d'un rendu serveur, donc il pourrait être fissuré.

Si vous avez js file one vérifier pour <element> des changements sur des éléments importants et js file two et js file three en vérifiant que ce fichier existe par période, vous aurez une restauration complète de l'intégrité sur la page au cours de la période.

Prenons un exemple des 4 fichiers et vous montrons ce que je veux dire.

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

Maintenant, c'est juste pour montrer que cela fonctionne sur tous les fichiers et balises

   #heading {
   background-color:red;
   }

Si vous mettez tous ces fichiers ensemble et construisez l'exemple, vous verrez la fonction de cette mesure. Cela empêchera certaines injections imprévues si vous l'implémentez correctement sur tous les éléments importants de votre fichier d'index, en particulier lorsque vous travaillez avec PHP.

Pourquoi j'ai choisi recharger au lieu de revenir à la valeur normale par attribut est le fait que certains attaquants pourraient avoir une autre partie du site déjà configuré et prêt et il diminue la quantité de code. Le rechargement supprimera tout le travail acharné de l'attaquant et il ira probablement jouer quelque part plus facilement.

Une autre note: Cela pourrait devenir beaucoup de code alors gardez-le propre et assurez-vous d'ajouter des définitions à l'endroit où ils appartiennent pour faciliter les modifications à l'avenir. Réglez également les secondes sur votre valeur préférée, car des intervalles de 1 seconde sur de grandes pages pourraient avoir des effets dramatiques sur les ordinateurs plus anciens que vos visiteurs pourraient utiliser


0
2018-03-04 03:16



une solution simple!

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

0
2018-06-04 06:54