Pertanyaan Bagaimana cara Facebook menonaktifkan Alat Pengembang yang terintegrasi dengan browser?


Jadi rupanya karena penipuan baru-baru ini, alat pengembang dimanfaatkan oleh orang untuk memposting spam dan bahkan digunakan untuk "meretas" akun. Facebook telah memblokir alat pengembang, dan saya bahkan tidak dapat menggunakan konsol.

Enter image description here

Bagaimana mereka melakukannya? Satu posting Stack Overflow mengklaim bahwa itu tidak mungkin, tetapi Facebook telah membuktikan mereka salah.

Cukup buka Facebook dan buka alat pengembang, ketik satu karakter ke konsol, dan peringatan ini muncul. Tidak peduli apa yang Anda masukkan, itu tidak akan dieksekusi.

Bagaimana ini mungkin?

Mereka bahkan memblokir pelengkapan otomatis di konsol:

Enter image description here


1560
2018-02-11 03:42


asal


Jawaban:


Saya seorang insinyur keamanan di Facebook dan ini adalah kesalahan saya. Kami menguji ini untuk beberapa pengguna untuk melihat apakah itu dapat memperlambat beberapa serangan di mana pengguna ditipu ke kode JavaScript paste (jahat) ke dalam konsol browser.

Hanya untuk menjadi jelas: mencoba memblokir peretas sisi-klien adalah a ide buruk secara umum; ini untuk melindungi terhadap serangan rekayasa sosial tertentu.

Jika Anda berada di grup uji dan terganggu oleh ini, maaf. Saya mencoba untuk membuat halaman opt-out yang lama (sekarang halaman bantuan) sesederhana mungkin namun masih cukup menakutkan untuk setidaknya berhenti beberapa dari para korban.

Kode sebenarnya sangat mirip dengan tautan @ joeldixon66; kami sedikit lebih rumit tanpa alasan.

Chrome membungkus semua kode konsol dalam

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

... jadi situs itu mengubah console._commandLineAPI untuk melempar:

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

Ini adalah tidak cukup (coba saja!), tapi itulah trik utama.


Epilog: Tim Chrome memutuskan bahwa mengalahkan konsol dari sisi pengguna JS adalah bug dan memperbaiki masalah, rendering teknik ini tidak valid. Setelah itu, perlindungan tambahan ditambahkan ke melindungi pengguna dari self-xss.


2281
2018-02-11 05:33



Saya menemukan skrip buster konsol Facebook menggunakan alat pengembang Chrome. Berikut adalah skrip dengan perubahan kecil agar terbaca. Saya telah menghapus bagian-bagian yang tidak dapat saya mengerti:

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

Dengan ini, pelengkapan otomatis konsol gagal secara diam-diam sementara pernyataan yang diketik di konsol akan gagal dijalankan (pengecualian akan dicatat).

Referensi:


72
2018-02-15 08:16



Saya tidak bisa memicunya di halaman mana pun. Versi yang lebih kuat dari ini akan melakukannya:

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

console.log('test');

Untuk memberi gaya pada output: Warna di konsol JavaScript

Edit Berpikir @ joeldixon66 memiliki ide yang tepat: Nonaktifkan eksekusi JavaScript dari konsol «::: KSpace :::


36
2018-02-11 04:02



Selain mendefinisikan ulang console._commandLineAPI, ada beberapa cara lain untuk masuk ke InjectedScriptHost di browser WebKit, untuk mencegah atau mengubah evaluasi ekspresi yang dimasukkan ke konsol pengembang.

Edit:

Chrome telah memperbaiki ini dalam rilis sebelumnya. - Yang pasti sebelum Februari 2015, ketika saya membuat intinya pada saat itu 

Jadi inilah kemungkinan lain. Kali ini kita masuk, level di atas, langsung masuk InjectedScript daripada InjectedScriptHost dibandingkan dengan versi sebelumnya.

Yang agak bagus, karena Anda dapat langsung melakukan patch monyet InjectedScript._evaluateAndWrap daripada harus bergantung pada InjectedScriptHost.evaluate karena itu memberi Anda kendali yang lebih baik atas apa yang seharusnya terjadi.

Hal lain yang cukup menarik adalah, kita dapat mencegat hasil internal ketika ekspresi dievaluasi dan kembalikan itu kepada pengguna, bukan perilaku normal.

Berikut adalah kode, yang melakukan hal itu, mengembalikan hasil internal ketika seorang pengguna mengevaluasi sesuatu di konsol.

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

Ini sedikit verbose, tapi saya pikir saya menaruh beberapa komentar ke dalamnya

Jadi biasanya, jika seorang pengguna, misalnya, mengevaluasi [1,2,3,4] Anda mengharapkan hasil sebagai berikut:

enter image description here 

Setelah monkeypatching InjectedScript._evaluateAndWrap mengevaluasi ekspresi yang sama, memberikan hasil sebagai berikut:

enter image description here

Ketika Anda melihat panah kecil-kiri, menunjukkan output, masih ada, tetapi kali ini kita mendapatkan objek. Di mana hasil ekspresi, array [1,2,3,4] direpresentasikan sebagai objek dengan semua properti yang dijelaskan.

Saya sarankan mencoba mengevaluasi ini dan ekspresi itu, termasuk yang menghasilkan kesalahan. Ini cukup menarik.

Selain itu, lihatlah is  - InjectedScriptHost - obyek. Ini menyediakan beberapa metode untuk bermain dan mendapatkan sedikit wawasan ke dalam bagian internal inspektur.

Tentu saja, Anda dapat mencegat semua informasi itu dan tetap mengembalikan hasil asli kepada pengguna.

Cukup ganti pernyataan kembali di jalur lain oleh a console.log (res) mengikuti a return res. Maka Anda akan berakhir dengan yang berikut ini.

enter image description here 

Akhir dari Sunting 


Ini adalah versi sebelumnya yang diperbaiki oleh Google. Oleh karena itu bukan cara yang mungkin lagi.

Salah satunya adalah mengaitkan Function.prototype.call

Chrome mengevaluasi ekspresi yang dimasukkan oleh calling fungsi evalnya dengan InjectedScriptHost sebagai thisArg


25
2018-02-19 14:49



Netflix juga mengimplementasikan fitur ini

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

Mereka hanya menimpa console._commandLineAPI untuk membuang kesalahan keamanan.


19
2018-03-06 06:20



Ini sebenarnya mungkin karena Facebook mampu melakukannya. Yah, bukan alat pengembang web yang sebenarnya tetapi eksekusi Javascript di konsol.

Lihat ini: Bagaimana cara Facebook menonaktifkan Alat Pengembang yang terintegrasi dengan browser?

Ini benar-benar tidak dapat melakukan banyak hal karena ada cara lain untuk melewati jenis keamanan sisi klien ini.

Ketika Anda mengatakan itu adalah sisi klien, itu terjadi di luar kendali server, jadi tidak banyak yang bisa Anda lakukan. Jika Anda bertanya mengapa Facebook masih melakukan ini, ini tidak benar-benar untuk keamanan tetapi untuk melindungi pengguna normal yang tidak tahu javascript dari menjalankan kode (bahwa mereka tidak tahu cara membaca) ke dalam konsol. Ini umum untuk situs yang menjanjikan layanan auto-liker atau bot fungsionalitas Facebook lainnya setelah Anda melakukan apa yang mereka minta Anda lakukan, di mana dalam banyak kasus, mereka memberi Anda jipascript javascript untuk berjalan di konsol.

Jika Anda tidak memiliki banyak pengguna seperti Facebook, maka saya tidak berpikir ada kebutuhan untuk melakukan apa yang dilakukan Facebook.

Bahkan jika Anda menonaktifkan Javascript di konsol, menjalankan javascript melalui address bar masih dimungkinkan.

enter image description here

enter image description here

dan jika browser menonaktifkan javascript di address bar, (Ketika Anda menempelkan kode ke address bar di Google Chrome, ia menghapus frase 'javascript:') menempelkan javascript ke salah satu tautan melalui elemen inspek masih mungkin dilakukan.

Periksa jangkar:

enter image description here

Tempel kode di href:

enter image description here

enter image description here

enter image description here

Intinya adalah validasi sisi server dan keamanan harus lebih dulu, kemudian lakukan setelah sisi klien.


18
2017-11-05 00:57



Chrome banyak berubah sejak kali facebook dapat menonaktifkan konsol ...

Per Maret 2017 ini tidak berfungsi lagi.

Yang terbaik yang dapat Anda lakukan adalah menonaktifkan beberapa fungsi konsol, contoh:

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



Cara saya yang sederhana, tetapi dapat membantu variasi lebih lanjut tentang subjek ini. Cantumkan semua metode dan ubah menjadi tidak berguna.

  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