¿Cómo deshabilita Facebook las herramientas de desarrollo integradas del navegador?
Frecuentes
Visto 296,227 equipos
1772
Entonces, aparentemente debido a las estafas recientes, las personas explotan las herramientas de desarrollo para publicar spam e incluso se usan para "hackear" cuentas. Facebook ha bloqueado las herramientas de desarrollo y ni siquiera puedo usar la consola.
como hicieron eso?? Una publicación de Stack Overflow afirmó que no es posible, pero Facebook les ha demostrado que estaban equivocados.
Simplemente vaya a Facebook y abra las herramientas de desarrollo, escriba un carácter en la consola y aparecerá esta advertencia. No importa lo que pongas, no se ejecutará.
¿Cómo es esto posible?
Incluso bloquearon el autocompletado en la consola:
14 Respuestas
2527
Soy ingeniero de seguridad en Facebook y esto es mi culpa. Estamos probando esto para algunos usuarios para ver si puede ralentizar algunos ataques en los que se engaña a los usuarios para que peguen código JavaScript (malicioso) en la consola del navegador.
Para que quede claro: tratar de bloquear a los piratas informáticos del lado del cliente es una mala idea en general; esto es para protegerse contra un ataque específico de ingeniería social.
Si terminó en el grupo de prueba y está molesto por esto, lo siento. Traté de hacer que la antigua página de exclusión voluntaria (ahora página de ayuda) lo más simple posible sin dejar de ser lo suficientemente aterrador como para detener al menos algo de las victimas
El código real es bastante similar a enlace de @joeldixon66; el nuestro es un poco más complicado sin una buena razón.
Chrome envuelve todo el código de la consola en
with ((console && console._commandLineAPI) || {}) {
<code goes here>
}
... entonces el sitio redefine console._commandLineAPI
tirar:
Object.defineProperty(console, '_commandLineAPI',
{ get : function() { throw 'Nooo!' } })
Es no es suficiente (¡pruébalo!), pero ese es el truco principal.
Epílogo: El equipo de Chrome decidió que derrotar a la consola desde el JS del lado del usuario era un error y solucionó el problema, invalidando esta técnica. Posteriormente, se añadió protección adicional a proteger a los usuarios de self-xss.
contestado el 23 de mayo de 17 a las 12:05
Chrome hizo una actualización, pero este tipo hizo una solución nuevamente: kspace.in/blog/2014/06/21/… - Roger Gajraj
@Alf, su página de exclusión ahora muestra la página de ayuda sin ninguna posibilidad de desactivar esta protección. - brazo.localhost
No rompa las herramientas de desarrollo debido a la estupidez de algunos usuarios. "Soluciones" como esta me hacen arder con la rabia de un millón de soles. - jonathan dunlap
Creo que Google necesita lanzar una versión "segura" de Chrome, sin DevTools, y obligar a cualquier persona con actualizaciones automáticas a cambiar a esta versión solo una vez. Cualquier desarrollador que realmente note la diferencia y necesite DevTools debería descargar la versión "aterradora". De hecho, etiquételos como "Miedo" y "Seguro" directamente en la página de descarga y disuada a los darwinianos de causarse daño declarando explícitamente que "Probablemente esté aquí porque un ataque de ingeniería social le dijo que descargara la versión Scary; por favor, no hacer esto." ¡Dios los bendiga, desarrolladores de FB, por ser tan creativos! - MonoZeus
@n00b Ese mensaje de advertencia es solo un console.log
. - campbell
97
Encontré el script buster de la consola de Facebook usando las herramientas de desarrollo de Chrome. Aquí está el guión con cambios menores para mejorar la legibilidad. He quitado las partes que no pude entender:
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);
Con esto, el autocompletado de la consola falla silenciosamente, mientras que las declaraciones escritas en la consola no se ejecutarán (se registrará la excepción).
Referencias:
Respondido 15 Feb 14, 14:02
49
No pude hacer que activara eso en ninguna página. Una versión más robusta de esto lo haría:
window.console.log = function(){
console.error('The developer console is temp...');
window.console.log = function() {
return false;
}
}
console.log('test');
Para aplicar estilo a la salida: Colores en la consola de JavaScript
Editar Ideas @joeldixon66 tiene la idea correcta: Deshabilitar la ejecución de JavaScript desde la consola « ::: KSpace :::
contestado el 23 de mayo de 17 a las 12:05
genial, pero aún así anular el mismo window.console.log = function(){//empty}
y use console.log - super genial
34
Además de redefinir console._commandLineAPI
, existen otras formas de acceder a InjectedScriptHost en los navegadores WebKit, para evitar o alterar la evaluación de las expresiones ingresadas en la consola del desarrollador.
Edit:
Chrome solucionó esto en una versión anterior. - que debe haber sido antes de febrero de 2015, ya que creé la esencia en ese momento
Así que aquí hay otra posibilidad. Esta vez nos enganchamos, un nivel más arriba, directamente a InjectedScript
más bien que InjectedScriptHost
a diferencia de la versión anterior.
Lo cual es bastante bueno, ya que puedes parchear directamente a los monos InjectedScript._evaluateAndWrap
en lugar de tener que depender de InjectedScriptHost.evaluate
ya que eso le da un control más detallado sobre lo que debería suceder.
Otra cosa bastante interesante es que podemos interceptar el resultado interno cuando se evalúa una expresión y devuelve eso al usuario en lugar del comportamiento normal.
Aquí está el código, que hace exactamente eso, devolver el resultado interno cuando un usuario evalúa algo en la consola.
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);
Es un poco detallado, pero pensé que puse algunos comentarios en él.
Normalmente, si un usuario, por ejemplo, evalúa [1,2,3,4]
usted esperaría el siguiente resultado:
Después de parchear monos InjectedScript._evaluateAndWrap
evaluando la misma expresión, da el siguiente resultado:
Como puede ver, la pequeña flecha izquierda, que indica la salida, todavía está allí, pero esta vez obtenemos un objeto. Donde el resultado de la expresión, la matriz [1,2,3,4]
se representa como un objeto con todas sus propiedades descritas.
Recomiendo tratar de evaluar esta y aquella expresión, incluidas las que generan errores. Es bastante interesante.
Además, eche un vistazo a la is
- InjectedScriptHost
- objeto. Proporciona algunos métodos para jugar y obtener un poco de información sobre el interior del inspector.
Por supuesto, podría interceptar toda esa información y aun así devolver el resultado original al usuario.
Simplemente reemplace la declaración de retorno en la ruta else por un console.log (res)
después de una return res
. Entonces terminarías con lo siguiente.
Fin de Editar
Esta es la versión anterior que fue reparada por Google. Por lo tanto, ya no es una forma posible.
Uno de ellos se está enganchando Function.prototype.call
Chrome evalúa la expresión ingresada por call
ing su función eval con InjectedScriptHost
as thisArg
var result = evalFunction.call(object, expression);
Dado esto, puede escuchar el thisArg
of call
"Ser" evaluate
y obtener una referencia al primer argumento (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);
}
};
}
Podría, por ejemplo, arrojar un error, que la evaluación fue rechazada.
Aquí se presenta una ejemplo donde la expresión ingresada se pasa a un compilador CoffeeScript antes de pasarla al evaluate
función.
respondido 13 nov., 17:05
29
Netflix también implementa esta característica
(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$$) {
}
})();
simplemente anulan console._commandLineAPI
para lanzar un error de seguridad.
respondido 06 mar '14, 06:03
27
Esto es realmente posible ya que Facebook pudo hacerlo. Bueno, no las herramientas de desarrollo web reales, sino la ejecución de Javascript en la consola.
Mira esto: ¿Cómo deshabilita Facebook las herramientas de desarrollo integradas del navegador?
Sin embargo, esto realmente no servirá de mucho, ya que hay otras formas de eludir este tipo de seguridad del lado del cliente.
Cuando dice que es del lado del cliente, sucede fuera del control del servidor, por lo que no hay mucho que pueda hacer al respecto. Si está preguntando por qué Facebook todavía hace esto, no es realmente por seguridad sino para proteger a los usuarios normales que no saben javascript de ejecutar código (que no saben cómo leer) en la consola. Esto es común para los sitios que prometen un servicio de Me gusta automático u otros bots de funcionalidad de Facebook después de que hagas lo que te piden que hagas, donde en la mayoría de los casos, te dan un fragmento de javascript para ejecutar en la consola.
Si no tienes tantos usuarios como Facebook, entonces no creo que haya necesidad de hacer lo que Facebook está haciendo.
Incluso si deshabilita Javascript en la consola, aún es posible ejecutar javascript a través de la barra de direcciones.
y si el navegador deshabilita javascript en la barra de direcciones, (cuando pega el código en la barra de direcciones en Google Chrome, elimina la frase 'javascript:') todavía es posible pegar javascript en uno de los enlaces a través del elemento de inspección.
Inspeccione el ancla:
Pegue el código en href:
La conclusión es la validación del lado del servidor y la seguridad debe ser lo primero, luego hacer el lado del cliente después.
Respondido 02 ago 17, 09:08
14
Chrome ha cambiado mucho desde los tiempos en que Facebook podía desactivar la consola...
A partir de marzo de 2017, esto ya no funciona.
Lo mejor que puedes hacer es deshabilitar algunas de las funciones de la consola, ejemplo:
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(){};
}
respondido 12 mar '17, 12:03
13
Mi manera simple, pero puede ayudar para más variaciones sobre este tema. Enumere todos los métodos y modifíquelos a inútiles.
Object.getOwnPropertyNames(console).filter(function(property) {
return typeof console[property] == 'function';
}).forEach(function (verb) {
console[verb] =function(){return 'Sorry, for security reasons...';};
});
Sin embargo, un mejor enfoque es deshabilitar la herramienta de desarrollador para que no se abra de ninguna manera significativa.
(function() {
'use strict';
Object.getOwnPropertyNames(console).filter(function(property) {
return typeof console[property] == 'function';
}).forEach(function (verb) {
console[verb] =function(){return 'Sorry, for security reasons...';};
});
window.addEventListener('devtools-opened', ()=>{
// do some extra code if needed or ...
// maybe even delete the page, I still like to add redirect just in case
window.location.href+="#";
window.document.head.innerHTML="";
window.document.body.innerHTML="devtools, page is now cleared";
});
window.addEventListener('devtools-closed', ()=>{
// do some extra code if needed
});
let verifyConsole = () => {
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > 100) { // user had to resume the script manually via opened dev tools
window.dispatchEvent(new Event('devtools-opened'));
}else{
window.dispatchEvent(new Event('devtools-closed'));
}
setTimeout(verifyConsole, 100);
}
verifyConsole();
})();
Respondido 10 ago 22, 11:08
5
Devtools internamente inyecta un IIFE llamado getCompletions
en la página, llamada cuando se presiona una tecla dentro de la consola de Devtools.
En cuanto al fuente de esa función, utiliza algunas funciones globales que se pueden sobrescribir.
Mediante el uso de la Error
constructor es posible obtener la pila de llamadas, que incluirá getCompletions
cuando es llamado por Devtools.
Ejemplo:
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);
});
respondido 13 nov., 18:18
Eso es bastante bueno, pero también bloquea la página. - Derek 朕 會 功夫
@Derek朕會功夫 La única forma (que he encontrado) de suprimir más entradas del usuario: sam denty
Me pregunto si puede arrojar un error en lugar de usar un ciclo infinito. Editar: Probado, no funciona. - Derek 朕 會 功夫
@Derek朕會功夫 está en un bloque de captura de prueba. Probablemente podría anular las funciones sobre el bloque, pero solo evitaría la finalización automática (no la evaluación) - sam denty
lamentablemente no funciona. Todavía puedo usar las herramientas de desarrollo presionando -> punto triple en Chrome -> más herramientas -> herramientas de desarrollo ... - Pablo Grei
1
Tengo una manera simple aquí:
window.console = function () {}
Respondido 19 Jul 22, 15:07
0
una solución sencilla!
setInterval(()=>console.clear(),1500);
Respondido el 04 de junio de 18 a las 07:06
¿Cómo desactiva esto el console.log()
? - Red
console.log()
ya no importa cuando la consola se limpia constantemente :) - Mohmmad Ebrahimi Aval
esta es una mala idea. el hacker puede rastrear desde su terminal y ver todos los registros. - soma hesk
y si marcas Preserve Logs, console.clear() no hace nada :P - zibrí
0
Iría por el camino de:
Object.defineProperty(window, 'console', {
get: function() {
},
set: function() {
}
});
respondido 14 nov., 18:11
-1
En Firefox no hace eso, ya que Firefox es un navegador para desarrolladores, creo que desde el comando WEBGL_debug_renderer_info is deprecated in Firefox and will be removed. Please use RENDERER
y el error Referrer Policy: Less restricted policies, including ‘no-referrer-when-downgrade’, ‘origin-when-cross-origin’ and ‘unsafe-url’, will be ignored soon for the cross-site request: https://static.xx.fbcdn.net/rsrc.php/v3/yS/r/XDDAHSZfaR6.js?_nc_x=Ij3Wp8lg5Kz
.
Respondido 19 Feb 22, 10:02
-2
Esta no es una medida de seguridad para dejar desatendido el código débil. Obtenga siempre una solución permanente para el código débil y asegure sus sitios web correctamente antes de implementar esta estrategia
La mejor herramienta, de lejos, según mi conocimiento, sería agregar varios archivos javascript que simplemente cambien la integridad de la página a la normalidad al actualizar o reemplazar el contenido. Deshabilitar esta herramienta de desarrollador no sería la mejor idea, ya que la omisión siempre está en duda, ya que el código es parte del navegador y no una representación del servidor, por lo que podría ser descifrado.
En caso tuvieses js file one
verificando para <element>
cambios en elementos importantes y js file two
y js file three
Al verificar que este archivo existe por período, tendrá una restauración de integridad completa en la página dentro del período.
Tomemos un ejemplo de los 4 archivos y mostremos lo que quiero decir.
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>
archivoprincipal.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
Ahora, esto es solo para mostrar que también funciona en todos los archivos y etiquetas.
#heading {
background-color:red;
}
Si junta todos estos archivos y crea el ejemplo, verá la función de esta medida. Esto evitará algunas inyecciones imprevistas si lo implementa correctamente en todos los elementos importantes de su archivo de índice, especialmente cuando trabaja con PHP.
El motivo por el que elegí recargar en lugar de volver a cambiar al valor normal por atributo es el hecho de que algunos atacantes podrían tener otra parte del sitio web ya configurada y lista, lo que reduce la cantidad de código. La recarga eliminará todo el trabajo duro del atacante y probablemente irá a jugar a un lugar más fácil.
Otra nota: Esto podría convertirse en una gran cantidad de código, así que manténgalo limpio y asegúrese de agregar definiciones a las que pertenecen para facilitar las ediciones en el futuro. También configure los segundos en la cantidad que prefiera, ya que los intervalos de 1 segundo en páginas grandes podrían tener efectos drásticos en las computadoras más antiguas que sus visitantes podrían estar usando.
respondido 04 mar '18, 04:03
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript facebook google-chrome-devtools or haz tu propia pregunta.
Solo por diversión: console.log = function() {} - tnt-rox
¿Encontró una solución para cómo bloquearon la función de autocompletar en la consola? Akshay Hegde
@AkshayHegde Fue un efecto secundario causado por el bloqueo de cualquier ejecución de código de las herramientas de desarrollo. - Derek 朕會功夫
@Derek朕會功夫, ¿puede compartir el código? Akshay Hegde
solo para tu información, ya no está bloqueado en Chrome. - John Lord